Skip to content

Conversation

@onmax
Copy link

@onmax onmax commented Jan 17, 2026

Add Nuxt framework guide + working example using nuxt-convex and @onmax/nuxt-better-auth.

Related #42

@vercel
Copy link

vercel bot commented Jan 17, 2026

@onmax is attempting to deploy a commit to the Convex Team on Vercel.

A member of the Team first needs to authorize it.

@coderabbitai
Copy link

coderabbitai bot commented Jan 17, 2026

📝 Walkthrough

Walkthrough

Adds documentation for Nuxt framework integration with Convex and Better Auth. Updates the framework guides index to include Nuxt alongside existing frameworks like React, Next, and SvelteKit. Includes comprehensive setup and usage instructions with code examples.

Changes

Cohort / File(s) Summary
Framework Guides Index
docs/content/docs/framework-guides/meta.json
Adds "nuxt" to the pages array in the correct alphabetical position between "next" and "sveltekit"
Nuxt Integration Guide
docs/content/docs/framework-guides/nuxt.mdx
New documentation file covering Nuxt + Convex + Better Auth integration, including installation, configuration (nuxt.config.ts, server/auth.config.ts), Convex functions (convex/users.ts), and client-side usage examples across multiple Vue pages

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 A new path for Nuxt now appears,
Convex guides through the frontend frontier,
Configuration and auth all aligned,
Documentation pristine and refined! ✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Title check ✅ Passed The pull request title 'docs: add Nuxt framework guide' accurately summarizes the main changes, which involve adding a new Nuxt framework guide documentation and related resources.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@examples/nuxt/convex/auth.ts`:
- Around line 9-18: Replace the non-null assertion on process.env.SITE_URL with
an explicit presence check so the app fails fast with a clear error; locate the
SITE_URL usage (the siteUrl constant and createAuth which calls betterAuth) and
throw or log a descriptive error (e.g., "SITE_URL environment variable is
required for OAuth and email verification") if process.env.SITE_URL is undefined
before passing baseURL to betterAuth; ensure the check runs at module
initialization so createAuth/betterAuth never receive an undefined baseURL.
🧹 Nitpick comments (2)
examples/nuxt/server/routes/auth/[...all].ts (1)

1-4: Verify event.context.auth is always injected (otherwise this will throw).

If auth isn’t set by the Nuxt server auth setup, this route will crash at runtime. Consider a small guard to fail fast with a clearer error.

🔧 Suggested guard
 export default defineEventHandler(async (event) => {
-  const { auth } = event.context;
-  return auth.handler(toWebRequest(event));
+  const auth = event.context?.auth;
+  if (!auth?.handler) {
+    throw new Error("Auth handler not initialized on event.context.auth");
+  }
+  return auth.handler(toWebRequest(event));
 });
examples/nuxt/nuxt.config.ts (1)

11-13: Protect nested dashboard routes as well.

Line 12 currently protects only /dashboard. The pattern /dashboard/** matches /dashboard/foo and deeper paths, but not /dashboard itself. If you add nested dashboard pages later, they need explicit protection. Specify both the base path and subpaths:

♻️ Suggested change
  routeRules: {
-    '/dashboard': { betterAuth: { requireAuth: true } },
+    '/dashboard': { betterAuth: { requireAuth: true } },
+    '/dashboard/**': { betterAuth: { requireAuth: true } },
  },

Comment on lines 9 to 18
const siteUrl = process.env.SITE_URL!;

// The component client has methods needed for integrating Convex with Better Auth,
// as well as helper methods for general use.
export const authComponent = createClient<DataModel>(components.betterAuth);

export const createAuth = (ctx: GenericCtx<DataModel>) => {
return betterAuth({
baseURL: siteUrl,
database: authComponent.adapter(ctx),
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🌐 Web query:

Better Auth baseURL email password flows required

💡 Result:

Here are the essentials for using Better Auth’s email+password flows and base URL requirements.

  • Enable email/password in your server auth config:

    • set emailAndPassword.enabled = true in betterAuth(...). [1][2]
  • Client endpoints (standard REST paths):

    • Sign up: POST /sign-up/email — fields: name, email, password, image?, callbackURL?.
    • Sign in: POST /sign-in/email — fields: email, password, rememberMe?, callbackURL?.
    • Password reset and verification flows exist and are implemented via hooks you provide (sendResetPassword, sendVerificationEmail). [2][5]
  • Password rules:

    • Default min length 8, max 128 (configurable). [2]
  • Email verification / required verification:

    • Option emailAndPassword.requireEmailVerification (if true, sign-in will require verified email and trigger sendVerificationEmail). [2]
  • Base URL / BETTER_AUTH_URL:

    • If your frontend and auth server are on different domains, behind proxies, or you use SSR, you should set BETTER_AUTH_URL (or configure the auth client baseURL) so redirect/callback URLs and CORS work correctly. It’s commonly required in multi-server or proxy setups. [0][4]
  • Hooks & customization:

    • Provide sendResetPassword/sendVerificationEmail implementations to actually send emails; you can customize callbackURL behavior. [5]
  • Quick refs:

    • Official site/docs (getting-started + email/password guide). [1][2]
    • GitHub repo for examples and config options. [1]

Sources:
[0] better-auth.com (home).
[1] better-auth GitHub.
[2] Better Auth — Email & Password docs.
[4] Discussion about BETTER_AUTH_URL usage (community/reddit).
[5] Better Auth — Email concepts (password reset hook).


🌐 Web query:

Convex Better Auth SITE_URL environment setup

💡 Result:

Steps to set SITE_URL for Convex + Better Auth

  1. Generate Better Auth secret (if not done):
    npx convex env set BETTER_AUTH_SECRET=$(openssl rand -base64 32). [1][2]

  2. Set your site URL for the Convex deployment (example local):
    npx convex env set SITE_URL http://localhost:3000. This SITE_URL is used for OAuth redirect callbacks and magic links. [2]

  3. Add the same SITE_URL to your local .env file used by your dev server (npx convex dev creates .env.local):
    SITE_URL=http://localhost:3000 (or VITE_SITE_URL / NEXT_PUBLIC_SITE_URL / VITE_SITE_URL per framework examples). [1][3]

  4. Configure Better Auth / Convex auth:

    • In convex/auth.config.ts, point your provider domain at process.env.CONVEX_SITE_URL.
    • In your auth initialization (convex/auth.ts), read base URL from process.env.SITE_URL and pass it to Better Auth. [1][3]

Notes:

  • CONVEX_SITE_URL (or NEXT_PUBLIC_CONVEX_SITE_URL / VITE_CONVEX_SITE_URL depending on framework) is the Convex deployment URL used as the provider domain; SITE_URL is your app’s public URL used for redirects. Set both appropriately for dev and production. [1][2]

Sources: [1] Better Auth Convex integration docs; [2] Convex manual auth setup.


Fail fast if SITE_URL is missing.

Line 9 uses a non-null assertion on a required environment variable. When unset, this crashes with a vague error instead of clearly indicating a configuration issue. SITE_URL is essential for OAuth callbacks and email verification flows in Convex + Better Auth.

🐛 Suggested change
-const siteUrl = process.env.SITE_URL!;
+const siteUrl = process.env.SITE_URL;
+if (!siteUrl) {
+  throw new Error("SITE_URL must be set in the Convex environment");
+}
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const siteUrl = process.env.SITE_URL!;
// The component client has methods needed for integrating Convex with Better Auth,
// as well as helper methods for general use.
export const authComponent = createClient<DataModel>(components.betterAuth);
export const createAuth = (ctx: GenericCtx<DataModel>) => {
return betterAuth({
baseURL: siteUrl,
database: authComponent.adapter(ctx),
const siteUrl = process.env.SITE_URL;
if (!siteUrl) {
throw new Error("SITE_URL must be set in the Convex environment");
}
// The component client has methods needed for integrating Convex with Better Auth,
// as well as helper methods for general use.
export const authComponent = createClient<DataModel>(components.betterAuth);
export const createAuth = (ctx: GenericCtx<DataModel>) => {
return betterAuth({
baseURL: siteUrl,
database: authComponent.adapter(ctx),
🤖 Prompt for AI Agents
In `@examples/nuxt/convex/auth.ts` around lines 9 - 18, Replace the non-null
assertion on process.env.SITE_URL with an explicit presence check so the app
fails fast with a clear error; locate the SITE_URL usage (the siteUrl constant
and createAuth which calls betterAuth) and throw or log a descriptive error
(e.g., "SITE_URL environment variable is required for OAuth and email
verification") if process.env.SITE_URL is undefined before passing baseURL to
betterAuth; ensure the check runs at module initialization so
createAuth/betterAuth never receive an undefined baseURL.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant