Skip to content

Commit a77142c

Browse files
authored
Merge pull request #17 from onmax/codex/convex-vue-migration
Switch to convex-vue and keep Nuxt composables
2 parents 65f58c7 + ae2d722 commit a77142c

15 files changed

Lines changed: 1292 additions & 722 deletions

File tree

docs/content/1.getting-started/2.installation.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ yarn add nuxt-convex convex
2525

2626
::
2727

28+
::note
29+
`nuxt-convex` ships with the recommended Vue integration (`convex-vue`), so you do not need to install it separately.
30+
::
31+
2832
Add the module to your Nuxt configuration:
2933

3034
```ts [nuxt.config.ts]
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
---
2+
title: useConvexPaginatedQuery
3+
description: Paginate Convex queries with real-time updates.
4+
---
5+
6+
Paginate a Convex query that returns a `PaginationResult`. This composable is **client-only** and subscribes to real-time updates. For SSR, use `useConvexQuery` and fetch a single page on the server.
7+
8+
## Usage
9+
10+
```vue [app/components/Tasks.vue]
11+
<script setup lang="ts">
12+
import { api } from '#convex/api'
13+
14+
const {
15+
data,
16+
pages,
17+
isDone,
18+
isLoading,
19+
isLoadingMore,
20+
loadMore,
21+
reset,
22+
} = useConvexPaginatedQuery(api.tasks.listPaginated, {}, { numItems: 20 })
23+
</script>
24+
25+
<template>
26+
<div v-if="isLoading">
27+
Loading…
28+
</div>
29+
<ul v-else>
30+
<li v-for="task in data" :key="task._id">
31+
{{ task.title }}
32+
</li>
33+
</ul>
34+
<button :disabled="isDone || isLoadingMore" @click="loadMore">
35+
Load more
36+
</button>
37+
<button @click="reset">
38+
Reset
39+
</button>
40+
</template>
41+
```
42+
43+
## Parameters
44+
45+
| Parameter | Type | Description |
46+
| --------- | ---------------------------- | ----------------------------------------------------- |
47+
| `query` | `FunctionReference<'query'>` | The paginated Convex query to call. |
48+
| `args` | `object` | Arguments for the query (excluding `paginationOpts`). |
49+
| `options` | `{ numItems: number }` | Number of items per page. |
50+
51+
## Return Values
52+
53+
| Property | Type | Description |
54+
| --------------- | ----------------------------------------------- | ------------------------------------------ |
55+
| `data` | `ComputedRef<T[]>` | Flattened list of all loaded pages. |
56+
| `pages` | `ComputedRef<T[][]>` | Array of pages. |
57+
| `lastPage` | `ComputedRef<PaginationResult<T> \| undefined>` | Last page result. |
58+
| `isDone` | `Ref<boolean>` | True when all pages are loaded. |
59+
| `isLoading` | `ComputedRef<boolean>` | True while the first page is loading. |
60+
| `isLoadingMore` | `Ref<boolean>` | True while loading additional pages. |
61+
| `loadMore` | `() => void` | Load the next page. |
62+
| `reset` | `() => void` | Clear pages and reload from the start. |
63+
| `suspense` | `() => Promise<T[][]>` | Resolves when the first page is available. |
64+
65+
## Components
66+
67+
`nuxt-convex` also includes renderless components for template usage:
68+
69+
### `<ConvexQuery>`
70+
71+
```vue
72+
<ConvexQuery :query="api.tasks.list" :args="{}">
73+
<template #loading>Loading…</template>
74+
<template #error="{ error }">Error: {{ error.message }}</template>
75+
<template #empty>No tasks yet.</template>
76+
<template #default="{ data }">
77+
<ul>
78+
<li v-for="task in data" :key="task._id">{{ task.title }}</li>
79+
</ul>
80+
</template>
81+
</ConvexQuery>
82+
```
83+
84+
### `<ConvexPaginatedQuery>`
85+
86+
```vue
87+
<ConvexPaginatedQuery :query="api.tasks.listPaginated" :args="{}" :options="{ numItems: 20 }">
88+
<template #loading>Loading…</template>
89+
<template #error="{ error, reset }">
90+
<div>Error: {{ error.message }}</div>
91+
<button @click="reset">Retry</button>
92+
</template>
93+
<template #empty>No tasks yet.</template>
94+
<template #default="{ data, loadMore, isDone }">
95+
<ul>
96+
<li v-for="task in data" :key="task._id">{{ task.title }}</li>
97+
</ul>
98+
<button :disabled="isDone" @click="loadMore">Load more</button>
99+
</template>
100+
</ConvexPaginatedQuery>
101+
```

docs/content/5.integrations/1.better-auth.md

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,8 +67,8 @@ Export CRUD functions that the Better Auth adapter will call:
6767
import { createApi } from '@convex-dev/better-auth'
6868
import schema from './schema'
6969

70-
export const { create, findOne, findMany, updateOne, updateMany, deleteOne, deleteMany } =
71-
createApi(schema, () => ({}))
70+
export const { create, findOne, findMany, updateOne, updateMany, deleteOne, deleteMany }
71+
= createApi(schema, () => ({}))
7272
```
7373

7474
### 7. Add Auth Tables to Schema
@@ -156,7 +156,9 @@ const { user, signIn, signOut } = useUserSession()
156156
<template>
157157
<div v-if="user">
158158
<p>Welcome, {{ user.name }}</p>
159-
<button @click="signOut()">Sign Out</button>
159+
<button @click="signOut()">
160+
Sign Out
161+
</button>
160162
</div>
161163
<div v-else>
162164
<button @click="signIn.social({ provider: 'github' })">
@@ -178,6 +180,7 @@ export default defineEventHandler(async (event) => {
178180
## Performance
179181

180182
HTTP latency to Convex (~50-200ms per DB call) is acceptable for auth operations:
183+
181184
- Login/signup are infrequent
182185
- Use JWE session cookies to minimize DB reads
183186
- Enable `cookieCache` for session caching

docs/content/5.integrations/index.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ navigation: false
99
Integrate nuxt-convex with popular authentication and other services.
1010

1111
::card-group
12-
::card{icon="i-simple-icons-auth0" title="Better Auth" to="/integrations/better-auth"}
13-
Use Convex as the database for Better Auth authentication.
14-
::
12+
::card{icon="i-simple-icons-auth0" title="Better Auth" to="/integrations/better-auth"}
13+
Use Convex as the database for Better Auth authentication.
14+
::
1515
::

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,9 @@
5858
"convex": ">=1.0.0"
5959
},
6060
"dependencies": {
61-
"@convex-vue/core": "^0.0.4",
6261
"@nuxt/kit": "catalog:prod",
6362
"consola": "catalog:prod",
63+
"convex-vue": "^0.1.5",
6464
"defu": "catalog:prod",
6565
"pathe": "catalog:prod"
6666
},

playground/app/auth.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { defineClientAuth } from '@onmax/nuxt-better-auth/config'
21
import { convexClient, crossDomainClient } from '@convex-dev/better-auth/client/plugins'
2+
import { defineClientAuth } from '@onmax/nuxt-better-auth/config'
33

44
export default defineClientAuth(() => ({
55
baseURL: `${import.meta.env.VITE_CONVEX_SITE_URL}/api/auth`,

playground/convex/auth.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,18 @@
11
import type { GenericCtx } from '@convex-dev/better-auth'
22
import type { DataModel } from './_generated/dataModel'
3+
import process from 'node:process'
34
import { createClient } from '@convex-dev/better-auth'
45
import { convex, crossDomain } from '@convex-dev/better-auth/plugins'
6+
import { betterAuth } from 'better-auth/minimal'
57
import { components } from './_generated/api'
68
import { query } from './_generated/server'
7-
import { betterAuth } from 'better-auth/minimal'
89
import authConfig from './auth.config'
910

1011
const siteUrl = process.env.SITE_URL!
1112

1213
export const authComponent = createClient<DataModel>(components.betterAuth)
1314

14-
export const createAuth = (ctx: GenericCtx<DataModel>) => {
15+
export function createAuth(ctx: GenericCtx<DataModel>): ReturnType<typeof betterAuth> {
1516
return betterAuth({
1617
trustedOrigins: [siteUrl],
1718
database: authComponent.adapter(ctx),

playground/convex/convex.config.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
1-
import { defineApp } from 'convex/server'
21
import betterAuth from '@convex-dev/better-auth/convex.config'
2+
import { defineApp } from 'convex/server'
33

44
const app = defineApp()
55
app.use(betterAuth)

0 commit comments

Comments
 (0)