Convex provides a real-time backend with automatic data synchronization. You can combine it with Better Auth to build applications where authenticated users access their own data with live updates.
The nuxt-convex module connects your Nuxt application to Convex. Better Auth handles authentication while Convex manages your application data.
npx nuxt module add nuxt-convex
Add both modules to your Nuxt configuration.
export default defineNuxtConfig({
modules: ['nuxt-convex', '@onmax/nuxt-better-auth'],
})
Better Auth provides the authenticated user through the useUserSession composable. You can pass the user ID to Convex queries to fetch user-specific data with real-time updates.
<script setup lang="ts">
import { api } from '#convex/api'
const { user } = useUserSession()
const { data: tasks } = useConvexQuery(
api.tasks.list,
computed(() => user.value ? { userId: user.value.id } : undefined),
{ ssr: false }
)
</script>
The computed wrapper ensures the query re-subscribes automatically when the user changes. When you pass undefined as the arguments, Convex pauses the query and returns no data. This behavior prevents unauthorized queries when the user is not authenticated.
{ ssr: false }. Convex queries executed on the server during SSR do not receive authentication cookies, which causes them to fail or return empty results.Better Auth typically stores authentication data in a SQL database. The @convex-dev/better-auth adapter lets you store users, sessions, and accounts directly in Convex instead. This approach keeps all your data in one place with Convex's real-time synchronization.
The adapter requires exact versions to ensure compatibility between Better Auth and Convex.
pnpm add @convex-dev/better-auth better-auth --save-exact
The Better Auth component registers the authentication tables in your Convex database.
import betterAuth from '@convex-dev/better-auth/convex.config'
import { defineApp } from 'convex/server'
const app = defineApp()
app.use(betterAuth)
export default app
The adapter replaces the standard database configuration in your auth config. The convex() plugin handles session management and token refresh through Convex.
import { components } from '#convex/api'
import { createClient } from '@convex-dev/better-auth'
import { convex } from '@convex-dev/better-auth/server/plugins'
import { defineServerAuth } from '@onmax/nuxt-better-auth/config'
const authComponent = createClient(components.betterAuth)
export default defineServerAuth({
database: authComponent.adapter(),
plugins: [convex()],
emailAndPassword: { enabled: true },
})