create-better-t-stack 3.9.0 → 3.10.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (64) hide show
  1. package/README.md +2 -1
  2. package/dist/cli.mjs +1 -1
  3. package/dist/index.mjs +1 -1
  4. package/dist/{src-DLvUK0Qf.mjs → src-QkFdHtZE.mjs} +17 -14
  5. package/package.json +38 -38
  6. package/templates/auth/better-auth/convex/backend/convex/auth.config.ts.hbs +5 -7
  7. package/templates/auth/better-auth/convex/backend/convex/auth.ts.hbs +16 -16
  8. package/templates/auth/better-auth/convex/backend/convex/http.ts.hbs +4 -4
  9. package/templates/auth/better-auth/convex/web/react/next/src/app/api/auth/[...all]/route.ts.hbs +2 -2
  10. package/templates/auth/better-auth/convex/web/react/next/src/components/user-menu.tsx.hbs +10 -10
  11. package/templates/auth/better-auth/convex/web/react/next/src/lib/auth-server.ts.hbs +13 -5
  12. package/templates/auth/better-auth/convex/web/react/tanstack-router/src/components/user-menu.tsx.hbs +14 -12
  13. package/templates/auth/better-auth/convex/web/react/tanstack-start/src/components/user-menu.tsx.hbs +13 -16
  14. package/templates/auth/better-auth/convex/web/react/tanstack-start/src/lib/auth-server.ts.hbs +11 -5
  15. package/templates/auth/better-auth/convex/web/react/tanstack-start/src/routes/api/auth/$.ts.hbs +4 -4
  16. package/templates/auth/better-auth/fullstack/tanstack-start/src/routes/api/auth/$.ts.hbs +1 -1
  17. package/templates/auth/better-auth/web/react/next/src/components/user-menu.tsx.hbs +17 -15
  18. package/templates/auth/better-auth/web/react/react-router/src/components/user-menu.tsx.hbs +16 -15
  19. package/templates/auth/better-auth/web/react/{tanstack-start/src/components/user-menu.tsx → tanstack-router/src/components/user-menu.tsx.hbs} +16 -15
  20. package/templates/auth/better-auth/web/react/{tanstack-router/src/components/user-menu.tsx → tanstack-start/src/components/user-menu.tsx.hbs} +16 -15
  21. package/templates/backend/convex/packages/backend/convex/README.md +4 -4
  22. package/templates/backend/convex/packages/backend/convex/tsconfig.json.hbs +1 -1
  23. package/templates/frontend/react/next/package.json.hbs +8 -7
  24. package/templates/frontend/react/next/src/app/layout.tsx.hbs +28 -1
  25. package/templates/frontend/react/next/src/components/mode-toggle.tsx.hbs +4 -6
  26. package/templates/frontend/react/next/src/components/providers.tsx.hbs +14 -4
  27. package/templates/frontend/react/react-router/package.json.hbs +2 -1
  28. package/templates/frontend/react/{tanstack-router/src/components/mode-toggle.tsx → react-router/src/components/mode-toggle.tsx.hbs} +4 -6
  29. package/templates/frontend/react/tanstack-router/package.json.hbs +2 -1
  30. package/templates/frontend/react/{react-router/src/components/mode-toggle.tsx → tanstack-router/src/components/mode-toggle.tsx.hbs} +4 -6
  31. package/templates/frontend/react/tanstack-start/package.json.hbs +2 -1
  32. package/templates/frontend/react/tanstack-start/src/router.tsx.hbs +6 -0
  33. package/templates/frontend/react/tanstack-start/src/routes/__root.tsx.hbs +13 -14
  34. package/templates/frontend/react/tanstack-start/vite.config.ts.hbs +5 -0
  35. package/templates/frontend/react/web-base/components.json +5 -2
  36. package/templates/frontend/react/web-base/src/components/ui/button.tsx.hbs +57 -0
  37. package/templates/frontend/react/web-base/src/components/ui/card.tsx.hbs +103 -0
  38. package/templates/frontend/react/web-base/src/components/ui/checkbox.tsx.hbs +26 -0
  39. package/templates/frontend/react/web-base/src/components/ui/dropdown-menu.tsx.hbs +262 -0
  40. package/templates/frontend/react/web-base/src/components/ui/input.tsx.hbs +20 -0
  41. package/templates/frontend/react/web-base/src/components/ui/label.tsx.hbs +20 -0
  42. package/templates/frontend/react/web-base/src/components/ui/skeleton.tsx.hbs +13 -0
  43. package/templates/frontend/react/web-base/src/components/ui/sonner.tsx.hbs +44 -0
  44. package/templates/frontend/react/web-base/src/index.css.hbs +57 -63
  45. package/templates/frontend/react/web-base/src/components/ui/button.tsx +0 -56
  46. package/templates/frontend/react/web-base/src/components/ui/card.tsx +0 -75
  47. package/templates/frontend/react/web-base/src/components/ui/checkbox.tsx +0 -27
  48. package/templates/frontend/react/web-base/src/components/ui/dropdown-menu.tsx +0 -228
  49. package/templates/frontend/react/web-base/src/components/ui/input.tsx +0 -21
  50. package/templates/frontend/react/web-base/src/components/ui/label.tsx +0 -19
  51. package/templates/frontend/react/web-base/src/components/ui/skeleton.tsx +0 -13
  52. package/templates/frontend/react/web-base/src/components/ui/sonner.tsx +0 -25
  53. /package/templates/auth/better-auth/web/react/tanstack-router/src/components/{sign-in-form.tsx → sign-in-form.tsx.hbs} +0 -0
  54. /package/templates/auth/better-auth/web/react/tanstack-router/src/components/{sign-up-form.tsx → sign-up-form.tsx.hbs} +0 -0
  55. /package/templates/auth/better-auth/web/react/tanstack-router/src/routes/{login.tsx → login.tsx.hbs} +0 -0
  56. /package/templates/auth/better-auth/web/react/tanstack-start/src/components/{sign-in-form.tsx → sign-in-form.tsx.hbs} +0 -0
  57. /package/templates/auth/better-auth/web/react/tanstack-start/src/components/{sign-up-form.tsx → sign-up-form.tsx.hbs} +0 -0
  58. /package/templates/auth/better-auth/web/react/tanstack-start/src/routes/{login.tsx → login.tsx.hbs} +0 -0
  59. /package/templates/auth/better-auth/web/solid/src/components/{sign-in-form.tsx → sign-in-form.tsx.hbs} +0 -0
  60. /package/templates/auth/better-auth/web/solid/src/components/{sign-up-form.tsx → sign-up-form.tsx.hbs} +0 -0
  61. /package/templates/auth/better-auth/web/solid/src/routes/{login.tsx → login.tsx.hbs} +0 -0
  62. /package/templates/frontend/react/react-router/src/components/{theme-provider.tsx → theme-provider.tsx.hbs} +0 -0
  63. /package/templates/frontend/react/tanstack-router/src/components/{theme-provider.tsx → theme-provider.tsx.hbs} +0 -0
  64. /package/templates/frontend/react/web-base/src/lib/{utils.ts → utils.ts.hbs} +0 -0
package/README.md CHANGED
@@ -38,7 +38,7 @@ Follow the prompts to configure your project or use the `--yes` flag for default
38
38
  | **Runtime** | • Bun<br>• Node.js<br>• Cloudflare Workers<br>• None |
39
39
  | **Database** | • SQLite<br>• PostgreSQL<br>• MySQL<br>• MongoDB<br>• None |
40
40
  | **ORM** | • Drizzle (TypeScript-first)<br>• Prisma (feature-rich)<br>• Mongoose (for MongoDB)<br>• None |
41
- | **Database Setup** | • Turso (SQLite)<br>• Cloudflare D1 (SQLite)<br>• Neon (PostgreSQL)<br>• Supabase (PostgreSQL)<br>• Prisma Postgres<br>• MongoDB Atlas<br>• None (manual setup) |
41
+ | **Database Setup** | • Turso (SQLite)<br>• Cloudflare D1 (SQLite)<br>• Neon (PostgreSQL)<br>• Supabase (PostgreSQL)<br>• Prisma Postgres<br>• MongoDB Atlas<br>• None (manual setup) |
42
42
  | **Authentication** | Better-Auth (email/password, with more options coming soon) |
43
43
  | **Styling** | Tailwind CSS with shadcn/ui components |
44
44
  | **Addons** | • PWA support<br>• Tauri (desktop applications)<br>• Starlight (documentation site)<br>• Biome (linting and formatting)<br>• Husky (Git hooks)<br>• Turborepo (optimized builds) |
@@ -77,6 +77,7 @@ Options:
77
77
  ## Telemetry
78
78
 
79
79
  This CLI collects anonymous usage data to help improve the tool. The data collected includes:
80
+
80
81
  - Configuration options selected
81
82
  - CLI version
82
83
  - Node.js version
package/dist/cli.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { n as createBtsCli } from "./src-DLvUK0Qf.mjs";
2
+ import { n as createBtsCli } from "./src-QkFdHtZE.mjs";
3
3
 
4
4
  //#region src/cli.ts
5
5
  createBtsCli().run();
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env node
2
- import { a as router, i as init, n as createBtsCli, o as sponsors, r as docs, t as builder } from "./src-DLvUK0Qf.mjs";
2
+ import { a as router, i as init, n as createBtsCli, o as sponsors, r as docs, t as builder } from "./src-QkFdHtZE.mjs";
3
3
 
4
4
  export { builder, createBtsCli, docs, init, router, sponsors };
@@ -95,7 +95,7 @@ const dependencyVersionMap = {
95
95
  "@vite-pwa/assets-generator": "^1.0.0",
96
96
  "@tauri-apps/cli": "^2.4.0",
97
97
  "@biomejs/biome": "^2.2.0",
98
- oxlint: "^1.32.0",
98
+ oxlint: "^1.34.0",
99
99
  oxfmt: "^0.19.0",
100
100
  husky: "^9.1.7",
101
101
  "lint-staged": "^16.1.2",
@@ -137,7 +137,7 @@ const dependencyVersionMap = {
137
137
  "convex-svelte": "^0.0.12",
138
138
  "convex-nuxt": "0.1.5",
139
139
  "convex-vue": "^0.1.5",
140
- "@convex-dev/better-auth": "^0.9.7",
140
+ "@convex-dev/better-auth": "^0.10.4",
141
141
  "@tanstack/svelte-query": "^5.85.3",
142
142
  "@tanstack/svelte-query-devtools": "^5.85.3",
143
143
  "@tanstack/vue-query-devtools": "^5.90.2",
@@ -4204,12 +4204,12 @@ async function setupAuth(config) {
4204
4204
  if (convexBackendDirExists) {
4205
4205
  await addPackageDependency({
4206
4206
  dependencies: ["better-auth", "@convex-dev/better-auth"],
4207
- customDependencies: { "better-auth": "1.3.34" },
4207
+ customDependencies: { "better-auth": "1.4.7" },
4208
4208
  projectDir: convexBackendDir
4209
4209
  });
4210
4210
  if (hasNativeForBA) await addPackageDependency({
4211
4211
  dependencies: ["@better-auth/expo"],
4212
- customDependencies: { "@better-auth/expo": "1.3.34" },
4212
+ customDependencies: { "@better-auth/expo": "1.4.7" },
4213
4213
  projectDir: convexBackendDir
4214
4214
  });
4215
4215
  }
@@ -4219,17 +4219,17 @@ async function setupAuth(config) {
4219
4219
  const hasViteReactOther = frontend.some((f) => ["tanstack-router", "react-router"].includes(f));
4220
4220
  if (hasNextJs) await addPackageDependency({
4221
4221
  dependencies: ["better-auth", "@convex-dev/better-auth"],
4222
- customDependencies: { "better-auth": "1.3.34" },
4222
+ customDependencies: { "better-auth": "1.4.7" },
4223
4223
  projectDir: clientDir
4224
4224
  });
4225
4225
  else if (hasTanStackStart) await addPackageDependency({
4226
4226
  dependencies: ["better-auth", "@convex-dev/better-auth"],
4227
- customDependencies: { "better-auth": "1.3.34" },
4227
+ customDependencies: { "better-auth": "1.4.7" },
4228
4228
  projectDir: clientDir
4229
4229
  });
4230
4230
  else if (hasViteReactOther) await addPackageDependency({
4231
4231
  dependencies: ["better-auth", "@convex-dev/better-auth"],
4232
- customDependencies: { "better-auth": "1.3.34" },
4232
+ customDependencies: { "better-auth": "1.4.7" },
4233
4233
  projectDir: clientDir
4234
4234
  });
4235
4235
  }
@@ -4243,8 +4243,8 @@ async function setupAuth(config) {
4243
4243
  "@convex-dev/better-auth"
4244
4244
  ],
4245
4245
  customDependencies: {
4246
- "better-auth": "1.3.34",
4247
- "@better-auth/expo": "1.3.34"
4246
+ "better-auth": "1.4.7",
4247
+ "@better-auth/expo": "1.4.7"
4248
4248
  },
4249
4249
  projectDir: nativeDir
4250
4250
  });
@@ -4486,10 +4486,11 @@ async function setupEnvironmentVariables(config) {
4486
4486
  const hasNative = frontend.includes("native-bare") || frontend.includes("native-uniwind") || frontend.includes("native-unistyles");
4487
4487
  const hasWeb = hasWebFrontend$1;
4488
4488
  if (!await fs.pathExists(envLocalPath) || !(await fs.readFile(envLocalPath, "utf8")).includes("npx convex env set")) {
4489
+ let siteUrlComments = "";
4490
+ if (hasWeb) siteUrlComments += "# npx convex env set SITE_URL http://localhost:3001\n";
4489
4491
  const convexCommands = `# Set Convex environment variables
4490
4492
  # npx convex env set BETTER_AUTH_SECRET=$(openssl rand -base64 32)
4491
- ${hasWeb ? "# npx convex env set SITE_URL http://localhost:3001\n" : ""}
4492
- `;
4493
+ ${siteUrlComments}`;
4493
4494
  await fs.appendFile(envLocalPath, convexCommands);
4494
4495
  }
4495
4496
  const convexBackendVars = [];
@@ -4507,7 +4508,8 @@ ${hasWeb ? "# npx convex env set SITE_URL http://localhost:3001\n" : ""}
4507
4508
  }, {
4508
4509
  key: "SITE_URL",
4509
4510
  value: "http://localhost:3001",
4510
- condition: true
4511
+ condition: true,
4512
+ comment: "Web app URL for authentication"
4511
4513
  });
4512
4514
  await addEnvVariablesToFile(envLocalPath, convexBackendVars);
4513
4515
  }
@@ -6148,7 +6150,7 @@ async function displayPostInstallInstructions(config) {
6148
6150
  const tauriInstructions = addons?.includes("tauri") ? getTauriInstructions(runCmd) : "";
6149
6151
  const huskyInstructions = hasHusky ? getHuskyInstructions(runCmd) : "";
6150
6152
  const lintingInstructions = hasLinting ? getLintingInstructions(runCmd) : "";
6151
- const nativeInstructions = (frontend?.includes("native-bare") || frontend?.includes("native-uniwind") || frontend?.includes("native-unistyles")) && backend !== "none" ? getNativeInstructions(isConvex, isBackendSelf, frontend || []) : "";
6153
+ const nativeInstructions = (frontend?.includes("native-bare") || frontend?.includes("native-uniwind") || frontend?.includes("native-unistyles")) && backend !== "none" ? getNativeInstructions(isConvex, isBackendSelf, frontend || [], runCmd) : "";
6152
6154
  const pwaInstructions = addons?.includes("pwa") && frontend?.includes("react-router") ? getPwaInstructions() : "";
6153
6155
  const starlightInstructions = addons?.includes("starlight") ? getStarlightInstructions(runCmd) : "";
6154
6156
  const clerkInstructions = isConvex && config.auth === "clerk" ? getClerkInstructions() : "";
@@ -6214,13 +6216,14 @@ async function displayPostInstallInstructions(config) {
6214
6216
  output += pc.cyan("https://github.com/AmanVarshney01/create-better-t-stack");
6215
6217
  consola$1.box(output);
6216
6218
  }
6217
- function getNativeInstructions(isConvex, isBackendSelf, _frontend) {
6219
+ function getNativeInstructions(isConvex, isBackendSelf, frontend, runCmd) {
6218
6220
  const envVar = isConvex ? "EXPO_PUBLIC_CONVEX_URL" : "EXPO_PUBLIC_SERVER_URL";
6219
6221
  const exampleUrl = isConvex ? "https://<YOUR_CONVEX_URL>" : isBackendSelf ? "http://<YOUR_LOCAL_IP>:3001" : "http://<YOUR_LOCAL_IP>:3000";
6220
6222
  const envFileName = ".env";
6221
6223
  const ipNote = isConvex ? "your Convex deployment URL (find after running 'dev:setup')" : "your local IP address";
6222
6224
  let instructions = `${pc.yellow("NOTE:")} For Expo connectivity issues, update\n apps/native/${envFileName} with ${ipNote}:\n ${`${envVar}=${exampleUrl}`}\n`;
6223
6225
  if (isConvex) instructions += `\n${pc.yellow("IMPORTANT:")} When using local development with Convex and native apps,\n ensure you use your local IP address instead of localhost or 127.0.0.1\n for proper connectivity.\n`;
6226
+ if (frontend.includes("native-unistyles")) instructions += `\n${pc.yellow("NOTE:")} Unistyles requires a development build.\n cd apps/native and run ${runCmd} android or ${runCmd} ios\n`;
6224
6227
  return instructions;
6225
6228
  }
6226
6229
  function getHuskyInstructions(runCmd) {
package/package.json CHANGED
@@ -1,52 +1,61 @@
1
1
  {
2
2
  "name": "create-better-t-stack",
3
- "version": "3.9.0",
3
+ "version": "3.10.0",
4
4
  "description": "A modern CLI tool for scaffolding end-to-end type-safe TypeScript projects with best practices and customizable configurations",
5
- "type": "module",
6
- "license": "MIT",
7
- "author": "Aman Varshney",
8
- "bin": {
9
- "create-better-t-stack": "dist/cli.mjs"
10
- },
11
- "files": [
12
- "templates",
13
- "dist"
14
- ],
15
5
  "keywords": [
6
+ "better-auth",
16
7
  "better-t-stack",
17
- "typescript",
8
+ "biome",
18
9
  "boilerplate",
19
- "starter",
20
10
  "cli",
21
- "turborepo",
22
- "trpc",
23
- "better-auth",
24
- "monorepo",
25
- "fullstack",
26
- "type-safety",
27
- "react",
28
- "react-native",
11
+ "drizzle",
12
+ "elysia",
29
13
  "expo",
14
+ "fullstack",
30
15
  "hono",
31
- "elysia",
32
- "drizzle",
16
+ "monorepo",
33
17
  "prisma",
34
- "tanstack",
35
- "tailwind",
36
- "shadcn",
37
18
  "pwa",
19
+ "react",
20
+ "react-native",
21
+ "shadcn",
22
+ "starter",
23
+ "tailwind",
24
+ "tanstack",
38
25
  "tauri",
39
- "biome"
26
+ "trpc",
27
+ "turborepo",
28
+ "type-safety",
29
+ "typescript"
40
30
  ],
31
+ "homepage": "https://better-t-stack.dev/",
32
+ "license": "MIT",
33
+ "author": "Aman Varshney",
41
34
  "repository": {
42
35
  "type": "git",
43
36
  "url": "git+https://github.com/AmanVarshney01/create-better-t-stack.git",
44
37
  "directory": "apps/cli"
45
38
  },
39
+ "bin": {
40
+ "create-better-t-stack": "dist/cli.mjs"
41
+ },
42
+ "files": [
43
+ "dist",
44
+ "templates"
45
+ ],
46
+ "type": "module",
47
+ "exports": {
48
+ ".": {
49
+ "types": "./dist/index.d.mts",
50
+ "import": "./dist/index.mjs"
51
+ },
52
+ "./cli": {
53
+ "import": "./dist/cli.mjs"
54
+ }
55
+ },
46
56
  "publishConfig": {
47
57
  "access": "public"
48
58
  },
49
- "homepage": "https://better-t-stack.dev/",
50
59
  "scripts": {
51
60
  "build": "tsdown --publint",
52
61
  "dev": "tsdown --watch",
@@ -57,17 +66,8 @@
57
66
  "test:ci": "bun run build && AGENT=1 bun test --bail=5",
58
67
  "prepublishOnly": "npm run build"
59
68
  },
60
- "exports": {
61
- ".": {
62
- "types": "./dist/index.d.mts",
63
- "import": "./dist/index.mjs"
64
- },
65
- "./cli": {
66
- "import": "./dist/cli.mjs"
67
- }
68
- },
69
69
  "dependencies": {
70
- "@better-t-stack/types": "^3.9.0",
70
+ "@better-t-stack/types": "^3.10.0",
71
71
  "@clack/prompts": "^1.0.0-alpha.8",
72
72
  "@orpc/server": "^1.12.2",
73
73
  "consola": "^3.4.2",
@@ -1,8 +1,6 @@
1
+ import { getAuthConfigProvider } from "@convex-dev/better-auth/auth-config";
2
+ import type { AuthConfig } from "convex/server";
3
+
1
4
  export default {
2
- providers: [
3
- {
4
- domain: process.env.CONVEX_SITE_URL,
5
- applicationID: "convex",
6
- },
7
- ],
8
- };
5
+ providers: [getAuthConfigProvider()],
6
+ } satisfies AuthConfig;
@@ -2,19 +2,21 @@ import { createClient, type GenericCtx } from "@convex-dev/better-auth";
2
2
  {{#if (or (includes frontend "native-bare") (includes frontend "native-uniwind") (includes frontend "native-unistyles"))}}
3
3
  import { convex } from "@convex-dev/better-auth/plugins";
4
4
  import { expo } from "@better-auth/expo";
5
+ {{else if (or (includes frontend "tanstack-router") (includes frontend "react-router") (includes frontend "nuxt") (includes frontend "svelte") (includes frontend "solid"))}}
6
+ import { convex, crossDomain } from "@convex-dev/better-auth/plugins";
5
7
  {{else}}
6
8
  import { convex } from "@convex-dev/better-auth/plugins";
7
9
  {{/if}}
8
- {{#if (or (includes frontend "tanstack-router") (includes frontend "react-router") (includes frontend "nuxt") (includes frontend "svelte") (includes frontend "solid"))}}
9
- import { crossDomain } from "@convex-dev/better-auth/plugins";
10
- {{/if}}
11
10
  import { components } from "./_generated/api";
12
11
  import { DataModel } from "./_generated/dataModel";
13
12
  import { query } from "./_generated/server";
14
13
  import { betterAuth } from "better-auth";
15
14
  import { v } from "convex/values";
15
+ import authConfig from "./auth.config";
16
16
 
17
- {{#if (or (includes frontend "tanstack-start") (includes frontend "next") (includes frontend "tanstack-router") (includes frontend "react-router") (includes frontend "nuxt") (includes frontend "svelte") (includes frontend "solid"))}}
17
+ {{#if (or (includes frontend "tanstack-start") (includes frontend "next"))}}
18
+ const siteUrl = process.env.SITE_URL!;
19
+ {{else if (or (includes frontend "tanstack-router") (includes frontend "react-router") (includes frontend "nuxt") (includes frontend "svelte") (includes frontend "solid"))}}
18
20
  const siteUrl = process.env.SITE_URL!;
19
21
  {{/if}}
20
22
  {{#if (or (includes frontend "native-bare") (includes frontend "native-uniwind") (includes frontend "native-unistyles"))}}
@@ -23,23 +25,19 @@ const nativeAppUrl = process.env.NATIVE_APP_URL || "mybettertapp://";
23
25
 
24
26
  export const authComponent = createClient<DataModel>(components.betterAuth);
25
27
 
26
- function createAuth(
27
- ctx: GenericCtx<DataModel>,
28
- { optionsOnly }: { optionsOnly?: boolean } = { optionsOnly: false }
29
- ) {
28
+ function createAuth(ctx: GenericCtx<DataModel>) {
30
29
  return betterAuth({
31
- logger: {
32
- disabled: optionsOnly,
33
- },
34
30
  {{#if (and (or (includes frontend "native-bare") (includes frontend "native-uniwind") (includes frontend "native-unistyles")) (or (includes frontend "tanstack-start") (includes frontend "next")))}}
35
31
  baseURL: siteUrl,
36
32
  trustedOrigins: [siteUrl, nativeAppUrl],
33
+ {{else if (and (or (includes frontend "native-bare") (includes frontend "native-uniwind") (includes frontend "native-unistyles")) (or (includes frontend "tanstack-router") (includes frontend "react-router") (includes frontend "nuxt") (includes frontend "svelte") (includes frontend "solid")))}}
34
+ trustedOrigins: [siteUrl, nativeAppUrl],
37
35
  {{else if (or (includes frontend "native-bare") (includes frontend "native-uniwind") (includes frontend "native-unistyles"))}}
38
36
  trustedOrigins: [nativeAppUrl],
39
37
  {{else if (or (includes frontend "tanstack-start") (includes frontend "next"))}}
40
38
  baseURL: siteUrl,
41
39
  trustedOrigins: [siteUrl],
42
- {{else}}
40
+ {{else if (or (includes frontend "tanstack-router") (includes frontend "react-router") (includes frontend "nuxt") (includes frontend "svelte") (includes frontend "solid"))}}
43
41
  trustedOrigins: [siteUrl],
44
42
  {{/if}}
45
43
  database: authComponent.adapter(ctx),
@@ -50,11 +48,13 @@ function createAuth(
50
48
  plugins: [
51
49
  {{#if (or (includes frontend "native-bare") (includes frontend "native-uniwind") (includes frontend "native-unistyles"))}}
52
50
  expo(),
53
- {{/if}}
54
- {{#if (or (includes frontend "tanstack-router") (includes frontend "react-router") (includes frontend "nuxt") (includes frontend "svelte") (includes frontend "solid"))}}
51
+ {{else if (or (includes frontend "tanstack-router") (includes frontend "react-router") (includes frontend "nuxt") (includes frontend "svelte") (includes frontend "solid"))}}
55
52
  crossDomain({ siteUrl }),
56
53
  {{/if}}
57
- convex(),
54
+ convex({
55
+ authConfig,
56
+ jwksRotateOnTokenGenerationError: true,
57
+ }),
58
58
  ],
59
59
  });
60
60
  }
@@ -67,4 +67,4 @@ export const getCurrentUser = query({
67
67
  handler: async function (ctx, args) {
68
68
  return authComponent.getAuthUser(ctx);
69
69
  },
70
- });
70
+ });
@@ -3,10 +3,10 @@ import { authComponent, createAuth } from "./auth";
3
3
 
4
4
  const http = httpRouter();
5
5
 
6
- {{#if (or (includes frontend "tanstack-start") (includes frontend "next") (includes frontend "native-bare") (includes frontend "native-uniwind") (includes frontend "native-unistyles"))}}
7
- authComponent.registerRoutes(http, createAuth);
8
- {{else}}
6
+ {{#if (or (includes frontend "tanstack-router") (includes frontend "react-router") (includes frontend "nuxt") (includes frontend "svelte") (includes frontend "solid"))}}
9
7
  authComponent.registerRoutes(http, createAuth, { cors: true });
8
+ {{else}}
9
+ authComponent.registerRoutes(http, createAuth);
10
10
  {{/if}}
11
11
 
12
- export default http;
12
+ export default http;
@@ -1,3 +1,3 @@
1
- import { nextJsHandler } from "@convex-dev/better-auth/nextjs";
1
+ import { handler } from "@/lib/auth-server";
2
2
 
3
- export const { GET, POST } = nextJsHandler();
3
+ export const { GET, POST } = handler;
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  DropdownMenu,
3
3
  DropdownMenuContent,
4
+ DropdownMenuGroup,
4
5
  DropdownMenuItem,
5
6
  DropdownMenuLabel,
6
7
  DropdownMenuSeparator,
@@ -18,17 +19,16 @@ export default function UserMenu() {
18
19
 
19
20
  return (
20
21
  <DropdownMenu>
21
- <DropdownMenuTrigger asChild>
22
- <Button variant="outline">{user?.name}</Button>
22
+ <DropdownMenuTrigger render={<Button variant="outline" />}>
23
+ {user?.name}
23
24
  </DropdownMenuTrigger>
24
25
  <DropdownMenuContent className="bg-card">
25
- <DropdownMenuLabel>My Account</DropdownMenuLabel>
26
- <DropdownMenuSeparator />
27
- <DropdownMenuItem>{user?.email}</DropdownMenuItem>
28
- <DropdownMenuItem asChild>
29
- <Button
26
+ <DropdownMenuGroup>
27
+ <DropdownMenuLabel>My Account</DropdownMenuLabel>
28
+ <DropdownMenuSeparator />
29
+ <DropdownMenuItem>{user?.email}</DropdownMenuItem>
30
+ <DropdownMenuItem
30
31
  variant="destructive"
31
- className="w-full"
32
32
  onClick={() => {
33
33
  authClient.signOut({
34
34
  fetchOptions: {
@@ -40,8 +40,8 @@ export default function UserMenu() {
40
40
  }}
41
41
  >
42
42
  Sign Out
43
- </Button>
44
- </DropdownMenuItem>
43
+ </DropdownMenuItem>
44
+ </DropdownMenuGroup>
45
45
  </DropdownMenuContent>
46
46
  </DropdownMenu>
47
47
  );
@@ -1,6 +1,14 @@
1
- import { createAuth } from "@{{projectName}}/backend/convex/auth";
2
- import { getToken as getTokenNextjs } from "@convex-dev/better-auth/nextjs";
1
+ import { convexBetterAuthNextJs } from "@convex-dev/better-auth/nextjs";
3
2
 
4
- export const getToken = () => {
5
- return getTokenNextjs(createAuth);
6
- };
3
+ export const {
4
+ handler,
5
+ preloadAuthQuery,
6
+ isAuthenticated,
7
+ getToken,
8
+ fetchAuthQuery,
9
+ fetchAuthMutation,
10
+ fetchAuthAction,
11
+ } = convexBetterAuthNextJs({
12
+ convexUrl: process.env.NEXT_PUBLIC_CONVEX_URL!,
13
+ convexSiteUrl: process.env.NEXT_PUBLIC_CONVEX_SITE_URL!,
14
+ });
@@ -1,34 +1,36 @@
1
+ import { useNavigate } from "@tanstack/react-router";
2
+
1
3
  import {
2
4
  DropdownMenu,
3
5
  DropdownMenuContent,
6
+ DropdownMenuGroup,
4
7
  DropdownMenuItem,
5
8
  DropdownMenuLabel,
6
9
  DropdownMenuSeparator,
7
10
  DropdownMenuTrigger,
8
11
  } from "@/components/ui/dropdown-menu";
9
12
  import { authClient } from "@/lib/auth-client";
10
- import { useNavigate } from "@tanstack/react-router";
11
- import { Button } from "./ui/button";
12
13
  import { useQuery } from "convex/react";
13
14
  import { api } from "@{{projectName}}/backend/convex/_generated/api";
14
15
 
16
+ import { Button } from "./ui/button";
17
+
15
18
  export default function UserMenu() {
16
19
  const navigate = useNavigate();
17
20
  const user = useQuery(api.auth.getCurrentUser)
18
21
 
19
22
  return (
20
23
  <DropdownMenu>
21
- <DropdownMenuTrigger asChild>
22
- <Button variant="outline">{user?.name}</Button>
24
+ <DropdownMenuTrigger render={<Button variant="outline" />}>
25
+ {user?.name}
23
26
  </DropdownMenuTrigger>
24
27
  <DropdownMenuContent className="bg-card">
25
- <DropdownMenuLabel>My Account</DropdownMenuLabel>
26
- <DropdownMenuSeparator />
27
- <DropdownMenuItem>{user?.email}</DropdownMenuItem>
28
- <DropdownMenuItem asChild>
29
- <Button
28
+ <DropdownMenuGroup>
29
+ <DropdownMenuLabel>My Account</DropdownMenuLabel>
30
+ <DropdownMenuSeparator />
31
+ <DropdownMenuItem>{user?.email}</DropdownMenuItem>
32
+ <DropdownMenuItem
30
33
  variant="destructive"
31
- className="w-full"
32
34
  onClick={() => {
33
35
  authClient.signOut({
34
36
  fetchOptions: {
@@ -42,8 +44,8 @@ export default function UserMenu() {
42
44
  }}
43
45
  >
44
46
  Sign Out
45
- </Button>
46
- </DropdownMenuItem>
47
+ </DropdownMenuItem>
48
+ </DropdownMenuGroup>
47
49
  </DropdownMenuContent>
48
50
  </DropdownMenu>
49
51
  );
@@ -1,49 +1,46 @@
1
1
  import {
2
2
  DropdownMenu,
3
3
  DropdownMenuContent,
4
+ DropdownMenuGroup,
4
5
  DropdownMenuItem,
5
6
  DropdownMenuLabel,
6
7
  DropdownMenuSeparator,
7
8
  DropdownMenuTrigger,
8
9
  } from "@/components/ui/dropdown-menu";
9
10
  import { authClient } from "@/lib/auth-client";
10
- import { useNavigate } from "@tanstack/react-router";
11
- import { Button } from "./ui/button";
12
11
  import { useQuery } from "convex/react";
13
12
  import { api } from "@{{projectName}}/backend/convex/_generated/api";
14
13
 
14
+ import { Button } from "./ui/button";
15
+
15
16
  export default function UserMenu() {
16
- const navigate = useNavigate();
17
17
  const user = useQuery(api.auth.getCurrentUser)
18
18
 
19
19
  return (
20
20
  <DropdownMenu>
21
- <DropdownMenuTrigger asChild>
22
- <Button variant="outline">{user?.name}</Button>
21
+ <DropdownMenuTrigger render={<Button variant="outline" />}>
22
+ {user?.name}
23
23
  </DropdownMenuTrigger>
24
24
  <DropdownMenuContent className="bg-card">
25
- <DropdownMenuLabel>My Account</DropdownMenuLabel>
26
- <DropdownMenuSeparator />
27
- <DropdownMenuItem>{user?.email}</DropdownMenuItem>
28
- <DropdownMenuItem asChild>
29
- <Button
25
+ <DropdownMenuGroup>
26
+ <DropdownMenuLabel>My Account</DropdownMenuLabel>
27
+ <DropdownMenuSeparator />
28
+ <DropdownMenuItem>{user?.email}</DropdownMenuItem>
29
+ <DropdownMenuItem
30
30
  variant="destructive"
31
- className="w-full"
32
31
  onClick={() => {
33
32
  authClient.signOut({
34
33
  fetchOptions: {
35
34
  onSuccess: () => {
36
- navigate({
37
- to: "/dashboard",
38
- });
35
+ location.reload();
39
36
  },
40
37
  },
41
38
  });
42
39
  }}
43
40
  >
44
41
  Sign Out
45
- </Button>
46
- </DropdownMenuItem>
42
+ </DropdownMenuItem>
43
+ </DropdownMenuGroup>
47
44
  </DropdownMenuContent>
48
45
  </DropdownMenu>
49
46
  );
@@ -1,6 +1,12 @@
1
- import { createAuth } from "@{{projectName}}/backend/convex/auth";
2
- import { setupFetchClient } from "@convex-dev/better-auth/react-start";
3
- import { getCookie } from "@tanstack/react-start/server";
1
+ import { convexBetterAuthReactStart } from "@convex-dev/better-auth/react-start";
4
2
 
5
- export const { fetchQuery, fetchMutation, fetchAction } =
6
- await setupFetchClient(createAuth, getCookie);
3
+ export const {
4
+ handler,
5
+ getToken,
6
+ fetchAuthQuery,
7
+ fetchAuthMutation,
8
+ fetchAuthAction,
9
+ } = convexBetterAuthReactStart({
10
+ convexUrl: process.env.VITE_CONVEX_URL!,
11
+ convexSiteUrl: process.env.VITE_CONVEX_SITE_URL!,
12
+ });
@@ -1,11 +1,11 @@
1
- import { reactStartHandler } from "@convex-dev/better-auth/react-start";
2
1
  import { createFileRoute } from "@tanstack/react-router";
2
+ import { handler } from "@/lib/auth-server";
3
3
 
4
4
  export const Route = createFileRoute("/api/auth/$")({
5
5
  server: {
6
6
  handlers: {
7
- GET: ({ request }) => reactStartHandler(request),
8
- POST: ({ request }) => reactStartHandler(request),
7
+ GET: ({ request }) => handler(request),
8
+ POST: ({ request }) => handler(request),
9
9
  },
10
10
  },
11
- });
11
+ });
@@ -12,4 +12,4 @@ export const Route = createFileRoute('/api/auth/$')({
12
12
  },
13
13
  },
14
14
  },
15
- })
15
+ })