Getting Started

Installation

Install and configure the Convex Nuxt module in your project.

Prerequisites

Before installing, make sure you have:

  • A Nuxt 3.x project
  • A Convex project with functions defined
New to Convex? Follow the Convex quickstart guide to set up your backend first.

Install the Module

pnpm add better-convex-nuxt

Configure Nuxt

Add the module to your nuxt.config.ts:

nuxt.config.ts
export default defineNuxtConfig({
  modules: ['better-convex-nuxt'],

  convex: {
    url: process.env.CONVEX_URL,
  },
})

Environment Variables

Important: By default, Convex CLI writes to .env.local while Nuxt reads from .env. You need to configure them to share the same file.

Step 1: Run Convex dev to generate .env.local with your CONVEX_URL:

pnpm convex dev

This creates .env.local containing:

.env.local
CONVEX_URL=https://your-project-123.convex.cloud
CONVEX_DEPLOYMENT=dev:your-project-123

Step 2: Update your package.json to tell Nuxt to read from .env.local:

package.json
{
  "scripts": {
    "dev": "nuxt dev --dotenv .env.local"
  }
}

Now both tools share the same environment file:

  • pnpm convex dev → writes to .env.local
  • pnpm dev → reads from .env.local (via --dotenv flag)

Verify Installation

Create a simple query to verify everything works:

app.vue
<script setup lang="ts">
import { api } from '~/convex/_generated/api'

const { data, status } = useConvexQuery(api.tasks.list, {})
</script>

<template>
  <div>
    <p v-if="status === 'pending'">Loading...</p>
    <p v-else-if="status === 'error'">Error loading tasks</p>
    <p v-else>Found {{ data?.length ?? 0 }} tasks</p>
  </div>
</template>

If you see your task count, you're all set!

Module Options

The module accepts these configuration options:

OptionTypeDefaultDescription
urlstringprocess.env.CONVEX_URLConvex deployment URL (WebSocket)
trustedOriginsstring[][]Additional trusted origins for CORS on auth proxy
permissionsbooleanfalseEnable createPermissions factory for RBAC
logging.enabledboolean | 'debug'falseEnable logging (true = info, 'debug' = verbose)
logging.format'pretty' | 'json''pretty'Output format for logs
nuxt.config.ts
export default defineNuxtConfig({
  modules: ['better-convex-nuxt'],

  convex: {
    url: process.env.CONVEX_URL,
    permissions: true, // Enable permission composables
    logging: {
      enabled: process.env.NODE_ENV === 'development', // Enable in dev
    },
  },
})

URL Configuration

The module automatically derives the Convex HTTP site URL from your CONVEX_URL:

  • https://your-project.convex.cloudhttps://your-project.convex.site
Do not manually set siteUrl unless you're using a custom domain. Setting it to localhost or your app's URL will cause a self-request deadlock during SSR auth.

For custom Convex domains, you can override the auto-derived URL:

nuxt.config.ts
export default defineNuxtConfig({
  convex: {
    url: process.env.CONVEX_URL,
    siteUrl: 'https://api.your-custom-domain.com', // Only for custom domains
  },
})

CORS Configuration

The auth proxy validates request origins against siteUrl by default. For multi-domain setups (staging, preview deployments), add trusted origins:

nuxt.config.ts
export default defineNuxtConfig({
  convex: {
    url: process.env.CONVEX_URL,
    trustedOrigins: [
      'https://staging.myapp.com',
      'https://preview-*.vercel.app', // Wildcard for preview deployments
    ],
  },
})
Origins are validated using exact match or wildcard patterns. Use * to match any substring (e.g., https://preview-*.vercel.app matches https://preview-abc123.vercel.app).

Environment Variables

VariableMaps ToDescription
CONVEX_URLconvex.urlConvex deployment URL
Note on URLs:CONVEX_URL is the only URL you need to set for the module. The Convex HTTP site URL is auto-derived. SITE_URL (used by Better Auth in Convex) is a separate variable for your app's public callback URL.

What's Included

The module automatically provides:

  • Auto-imported composables: useConvexQuery, useConvexMutation, useConvexAction, and more
  • Auth components: <ConvexAuthenticated>, <ConvexUnauthenticated>, <ConvexAuthLoading>
  • Server utilities: fetchQuery, fetchMutation, fetchAction for API routes
  • SSR support: Queries run on the server with automatic client hydration
  • Real-time subscriptions: Data syncs automatically via WebSocket

Troubleshooting

Convex Folder Location

This documentation assumes your Convex functions are in ~/convex (project root). If you use a different location, update your imports accordingly:

// Default: ~/convex
import { api } from '~/convex/_generated/api'

// If using src/convex
import { api } from '~/src/convex/_generated/api'

// If using a custom path
import { api } from '~/my-backend/_generated/api'

Environment Variables

Important: Environment variables are configured in two different places. This is a common source of confusion!

1. Nuxt App Environment (.env.local file)

If you followed the recommended setup, pnpm convex dev created .env.local with your CONVEX_URL. Add additional variables as needed:

.env.local
# Auto-generated by Convex CLI
CONVEX_URL=https://your-project-123.convex.cloud
CONVEX_DEPLOYMENT=dev:your-project-123

# Your app's public URL
# Development: use localhost
SITE_URL=http://localhost:3000
# Production: use your actual domain
# SITE_URL=https://your-app.com
Remember: If using .env.local, ensure your dev script includes --dotenv .env.local:
"dev": "nuxt dev --dotenv .env.local"

2. Convex Dashboard Environment

Set these in the Convex Dashboard under Settings > Environment Variables:

# Secret for Better Auth (generate with: openssl rand -base64 32)
BETTER_AUTH_SECRET=ULPDeGxMKBd7TOROpEZfGhHqCErVvB7QNGLW5DKCkNs=

# Static JWKS for token validation (see Performance docs for generation)
JWKS=[{"alg":"RS256","createdAt":...,"privateKey":"...","publicKey":"..."}]

# Must match your Nuxt app's SITE_URL!
SITE_URL=http://localhost:3000
SITE_URL must be set in BOTH places and must match exactly:
  • In your Nuxt .env.local (or .env) file
  • In Convex Dashboard environment variables
For production, update both to your actual domain (e.g., https://your-app.com).

After changing environment files, restart your dev server - Nuxt only reads environment variables at startup.

"CONVEX_URL not set" Error

This usually means Nuxt isn't reading the correct env file:

  1. Using .env.local? Ensure your dev script includes --dotenv .env.local
  2. Using .env? Verify the file exists in your project root and contains CONVEX_URL

Find your URL in the Convex dashboard under Settings.

Types Not Working

If TypeScript doesn't recognize Convex types, run:

npx convex dev

This generates the _generated/ folder with type definitions.

Auth Not Working

Common causes:

  1. SITE_URL mismatch - Most common issue! Ensure SITE_URL is identical in both:
    • Your Nuxt .env.local (or .env) file
    • Convex Dashboard environment variables
  2. Missing Convex env vars - Check these are set in Convex Dashboard:
    • BETTER_AUTH_SECRET
    • JWKS
    • SITE_URL
  3. Wrong localhost URL - Use http://localhost:3000 (not 127.0.0.1)
  4. JWKS not configured - See Static JWKS for setup

See Authentication for complete setup.


Next Steps

Quick Start

Build your first real-time feature

Queries

Learn about fetching data

Authentication

Set up user authentication