From ad1fc2494d6df38bd0fc365aceeb9b633e83ff20 Mon Sep 17 00:00:00 2001 From: Zak Stam Date: Fri, 25 Jul 2025 12:26:07 +0300 Subject: [PATCH 1/3] docs: add LLM Instructions section and Next.js guide to documentation --- docs/app/docs-sidebar.tsx | 12 + docs/app/page.tsx | 7 + .../convex-better-auth-guide-nextjs.tsx | 294 ++++++++++++++++++ 3 files changed, 313 insertions(+) create mode 100644 docs/components/sections/convex-better-auth-guide-nextjs.tsx diff --git a/docs/app/docs-sidebar.tsx b/docs/app/docs-sidebar.tsx index 2324421..392f52b 100644 --- a/docs/app/docs-sidebar.tsx +++ b/docs/app/docs-sidebar.tsx @@ -354,6 +354,18 @@ export default function DocsSidebar({ children }: React.PropsWithChildren) { + + + LLM Instructions + + + + + Next.js + + + + Users table diff --git a/docs/app/page.tsx b/docs/app/page.tsx index b4f7e62..66a5081 100644 --- a/docs/app/page.tsx +++ b/docs/app/page.tsx @@ -9,6 +9,7 @@ import { cx } from "class-variance-authority"; import { GenerateSecret } from "./generate-secret"; import { cn } from "@/lib/utils"; import { useSelectedVariant } from "@/app/code-block-variant-store"; +import ConvexBetterAuthGuideNextjs from "@/components/sections/convex-better-auth-guide-nextjs"; const CodeBlock = (props: ComponentProps) => ( @@ -3036,6 +3037,12 @@ export default function Home() { /> + +
+ + + +
); } diff --git a/docs/components/sections/convex-better-auth-guide-nextjs.tsx b/docs/components/sections/convex-better-auth-guide-nextjs.tsx new file mode 100644 index 0000000..98c54b4 --- /dev/null +++ b/docs/components/sections/convex-better-auth-guide-nextjs.tsx @@ -0,0 +1,294 @@ +"use client"; + +import { useState } from "react"; + +export default function ConvexBetterAuthGuideNextjs() { + const [isExpanded, setIsExpanded] = useState(false); + + const guideContent = `### These are steps to setup better auth with convex and nextjs + +# 1. Install the dependencies + +\`\`\`bash +npm install @convex-dev/better-auth +npm install better-auth@1.2.12 --save-exact +npm install convex@latest +\`\`\` + +# 2. Add a convex/auth.config.ts file to configure Better Auth as an authentication provider + +\`\`\`ts +// convex/auth.config.ts +export default { + providers: [ + { + // Your Convex site URL is provided in a system + // environment variable + domain: process.env.CONVEX_SITE_URL, + + // Application ID has to be "convex" + applicationID: "convex", + }, + ], +}; +\`\`\` + +# 3. Generate a secret for encryption and generating hashes. + +TIP: Make sure to check which port your Next.js app is running on (typically 3000) and adjust the BETTER_AUTH_URL accordingly + +\`\`\`bash +npx convex env set BETTER_AUTH_SECRET=$(openssl rand -base64 32) +npx convex env set BETTER_AUTH_URL=http://localhost:3000 +\`\`\` + +# 4. Add the Convex site URL environment variable to the .env.local file created by npx convex dev. It will be picked up by your framework dev server. + +\`\`\`bash +# Deployment used by \`npx convex dev\` +CONVEX_DEPLOYMENT=dev:adjective-animal-123 # team: team-name, project: project-name + +NEXT_PUBLIC_CONVEX_URL=https://adjective-animal-123.convex.cloud + +# Same as NEXT_PUBLIC_CONVEX_URL but ends in .site +NEXT_PUBLIC_CONVEX_SITE_URL=https://adjective-animal-123.convex.site +\`\`\` + +# 5. First, add a users table to your schema. Name it whatever you like. Better Auth has its own user table that tracks basic user data, so your application user table only needs fields specific to your app (or none at all). + +\`\`\`ts +// convex/schema.ts +import { defineSchema, defineTable } from "convex/server"; + +export default defineSchema({ + users: defineTable({ + // Fields are optional + }), +}); +\`\`\` + +# 6. Create your Better Auth instance. + +\`\`\`ts +// convex/lib/auth.ts +import { convexAdapter } from "@convex-dev/better-auth"; +import { convex } from "@convex-dev/better-auth/plugins"; +import { betterAuth } from "better-auth"; +import { betterAuthComponent } from "../convex/auth"; +import { type GenericCtx } from "../convex/_generated/server"; + +// You'll want to replace this with an environment variable +const siteUrl = "http://localhost:3000"; + +export const createAuth = (ctx: GenericCtx) => + // Configure your Better Auth instance here + betterAuth({ + // All auth requests will be proxied through your next.js server + baseURL: siteUrl, + database: convexAdapter(ctx, betterAuthComponent), + + // Simple non-verified email/password to get started + emailAndPassword: { + enabled: true, + requireEmailVerification: false, + }, + plugins: [ + // The Convex plugin is required + convex(), + ], + }); +\`\`\` + +\`\`\`ts +// convex/auth.ts +import { + BetterAuth, + type AuthFunctions, + type PublicAuthFunctions, +} from "@convex-dev/better-auth"; +import { api, components, internal } from "./_generated/api"; +import { query } from "./_generated/server"; +import type { Id, DataModel } from "./_generated/dataModel"; + +// Typesafe way to pass Convex functions defined in this file +const authFunctions: AuthFunctions = internal.auth; +const publicAuthFunctions: PublicAuthFunctions = api.auth; + +// Initialize the component +export const betterAuthComponent = new BetterAuth(components.betterAuth, { + authFunctions, + publicAuthFunctions, +}); + +// These are required named exports +export const { + createUser, + updateUser, + deleteUser, + createSession, + isAuthenticated, +} = betterAuthComponent.createAuthFunctions({ + // Must create a user and return the user id + onCreateUser: async (ctx, user) => { + return ctx.db.insert("users", {}); + }, + + // Delete the user when they are deleted from Better Auth + onDeleteUser: async (ctx, userId) => { + await ctx.db.delete(userId as Id<"users">); + }, +}); + +// Example function for getting the current user +// Feel free to edit, omit, etc. +export const getCurrentUser = query({ + args: {}, + handler: async (ctx) => { + // Get user data from Better Auth - email, name, image, etc. + const userMetadata = await betterAuthComponent.getAuthUser(ctx); + if (!userMetadata) { + return null; + } + // Get user data from your application's database + // (skip this if you have no fields in your users table schema) + const user = await ctx.db.get(userMetadata.userId as Id<"users">); + return { + ...user, + ...userMetadata, + }; + }, +}); +\`\`\` + +# 7. Create a Better Auth client instance for interacting with the Better Auth server from your client. + +\`\`\`ts +// lib/auth-client.ts +import { createAuthClient } from "better-auth/react"; +import { convexClient } from "@convex-dev/better-auth/client/plugins"; + +export const authClient = createAuthClient({ + plugins: [convexClient()], +}); +\`\`\` + +# 8. Register Better Auth route handlers on your Convex deployment. + +\`\`\`ts +import { httpRouter } from "convex/server"; +import { betterAuthComponent } from "./auth"; +import { createAuth } from "../lib/auth"; + +const http = httpRouter(); + +betterAuthComponent.registerRoutes(http, createAuth); + +export default http; +\`\`\` + +# 9. Set up route handlers to proxy auth requests from your framework server to your Convex deployment. + +\`\`\`ts +import { nextJsHandler } from "@convex-dev/better-auth/nextjs"; + +export const { GET, POST } = nextJsHandler(); +\`\`\` + +# 10. Wrap your app with the ConvexBetterAuthProvider component. + +\`\`\`ts +"use client"; + +import { ReactNode } from "react"; +import { ConvexReactClient } from "convex/react"; +import { authClient } from "@/lib/auth-client"; +import { ConvexBetterAuthProvider } from "@convex-dev/better-auth/react"; + +const convex = new ConvexReactClient(process.env.NEXT_PUBLIC_CONVEX_URL!); + +export function ConvexClientProvider({ children }: { children: ReactNode }) { + return ( + + {children} + + ); +} +\`\`\``; + + const previewContent = `### These are steps to setup better auth with convex and nextjs + +# 1. Install the dependencies + +\`\`\`bash +npm install @convex-dev/better-auth +npm install better-auth@1.2.12 --save-exact +npm install convex@latest +\`\`\` + +# 2. Add a convex/auth.config.ts file to configure Better Auth... + +... and 8 more steps`; + + return ( +
+
+

LLM Instructions: Convex Better Auth Setup (Next.js)

+

+ Copy and paste these instructions to any LLM (Claude code, Cursor, Windsurf, etc.) to set up better auth with convex. +

+
+ +
+ {/* Header with toggle and copy button */} +
+ + + +
+ + {/* Content */} +
+
+            
+              {isExpanded ? guideContent : previewContent}
+            
+          
+ + {!isExpanded && ( +
+ )} +
+ + {/* Footer when collapsed */} + {!isExpanded && ( +
+ +
+ )} +
+
+ ); +} From 5eba699c5dd0ae3812e0911e80333ee6a6410d4c Mon Sep 17 00:00:00 2001 From: Zak Stam Date: Fri, 25 Jul 2025 15:30:31 +0300 Subject: [PATCH 2/3] Remove debug console.log statements from code-block component --- docs/app/code-block.tsx | 6 ------ 1 file changed, 6 deletions(-) diff --git a/docs/app/code-block.tsx b/docs/app/code-block.tsx index e5319cc..b57992d 100644 --- a/docs/app/code-block.tsx +++ b/docs/app/code-block.tsx @@ -91,9 +91,6 @@ function CodeBlockInternal({ return Array.from({ length: end - start + 1 }, (_, i) => start + i); }); const sorted = [...expandedLines].sort((a, b) => a - b); - if (lines.some((line) => Array.isArray(line))) { - console.log("sorted", sorted); - } const sections: HighlightedSection[] = []; let current: HighlightedSection = { start: sorted[0], end: sorted[0] }; @@ -106,9 +103,6 @@ function CodeBlockInternal({ } } sections.push(current); - if (lines.some((line) => Array.isArray(line))) { - console.log("sections", sections); - } return sections; }; From 2172d73aab5e9d77b67a18e8653277264a63e683 Mon Sep 17 00:00:00 2001 From: Zak Stam Date: Sat, 26 Jul 2025 11:26:50 +0300 Subject: [PATCH 3/3] Added missing convex.config.ts step --- .../convex-better-auth-guide-nextjs.tsx | 35 +++++++++++++------ 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/docs/components/sections/convex-better-auth-guide-nextjs.tsx b/docs/components/sections/convex-better-auth-guide-nextjs.tsx index 98c54b4..597ac94 100644 --- a/docs/components/sections/convex-better-auth-guide-nextjs.tsx +++ b/docs/components/sections/convex-better-auth-guide-nextjs.tsx @@ -33,7 +33,20 @@ export default { }; \`\`\` -# 3. Generate a secret for encryption and generating hashes. +# 3. Add the Better Auth plugin to your Convex app configuration + +\`\`\`ts +// convex/convex.config.ts +import { defineApp } from 'convex/server' +import betterAuth from '@convex-dev/better-auth/convex.config' + +const app = defineApp() +app.use(betterAuth) + +export default app +\`\`\` + +# 4. Generate a secret for encryption and generating hashes. TIP: Make sure to check which port your Next.js app is running on (typically 3000) and adjust the BETTER_AUTH_URL accordingly @@ -42,7 +55,7 @@ npx convex env set BETTER_AUTH_SECRET=$(openssl rand -base64 32) npx convex env set BETTER_AUTH_URL=http://localhost:3000 \`\`\` -# 4. Add the Convex site URL environment variable to the .env.local file created by npx convex dev. It will be picked up by your framework dev server. +# 5. Add the Convex site URL environment variable to the .env.local file created by npx convex dev. It will be picked up by your framework dev server. \`\`\`bash # Deployment used by \`npx convex dev\` @@ -54,7 +67,7 @@ NEXT_PUBLIC_CONVEX_URL=https://adjective-animal-123.convex.cloud NEXT_PUBLIC_CONVEX_SITE_URL=https://adjective-animal-123.convex.site \`\`\` -# 5. First, add a users table to your schema. Name it whatever you like. Better Auth has its own user table that tracks basic user data, so your application user table only needs fields specific to your app (or none at all). +# 6. First, add a users table to your schema. Name it whatever you like. Better Auth has its own user table that tracks basic user data, so your application user table only needs fields specific to your app (or none at all). \`\`\`ts // convex/schema.ts @@ -67,7 +80,7 @@ export default defineSchema({ }); \`\`\` -# 6. Create your Better Auth instance. +# 7. Create your Better Auth instance. \`\`\`ts // convex/lib/auth.ts @@ -160,7 +173,7 @@ export const getCurrentUser = query({ }); \`\`\` -# 7. Create a Better Auth client instance for interacting with the Better Auth server from your client. +# 8. Create a Better Auth client instance for interacting with the Better Auth server from your client. \`\`\`ts // lib/auth-client.ts @@ -172,7 +185,7 @@ export const authClient = createAuthClient({ }); \`\`\` -# 8. Register Better Auth route handlers on your Convex deployment. +# 9. Register Better Auth route handlers on your Convex deployment. \`\`\`ts import { httpRouter } from "convex/server"; @@ -186,7 +199,7 @@ betterAuthComponent.registerRoutes(http, createAuth); export default http; \`\`\` -# 9. Set up route handlers to proxy auth requests from your framework server to your Convex deployment. +# 10. Set up route handlers to proxy auth requests from your framework server to your Convex deployment. \`\`\`ts import { nextJsHandler } from "@convex-dev/better-auth/nextjs"; @@ -194,7 +207,7 @@ import { nextJsHandler } from "@convex-dev/better-auth/nextjs"; export const { GET, POST } = nextJsHandler(); \`\`\` -# 10. Wrap your app with the ConvexBetterAuthProvider component. +# 11. Wrap your app with the ConvexBetterAuthProvider component. \`\`\`ts "use client"; @@ -227,7 +240,7 @@ npm install convex@latest # 2. Add a convex/auth.config.ts file to configure Better Auth... -... and 8 more steps`; +... and 9 more steps`; return (
@@ -253,7 +266,7 @@ npm install convex@latest > - {isExpanded ? 'Hide Guide' : 'Show Complete Guide (10 steps)'} + {isExpanded ? 'Hide Guide' : 'Show Complete Guide (11 steps)'}
)}