create-better-t-stack 3.11.0 → 3.12.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 (71) hide show
  1. package/dist/chunk-Dt3mZKp0.mjs +24 -0
  2. package/dist/cli.mjs +1 -1
  3. package/dist/index.d.mts +40 -60
  4. package/dist/index.mjs +2 -2
  5. package/dist/{src-XVvJUQ_h.mjs → src-DBVnwTkj.mjs} +668 -631
  6. package/package.json +2 -2
  7. package/templates/addons/turborepo/turbo.json.hbs +13 -0
  8. package/templates/api/orpc/native/utils/orpc.ts.hbs +21 -20
  9. package/templates/api/orpc/web/nuxt/app/plugins/orpc.ts.hbs +3 -5
  10. package/templates/api/orpc/web/react/base/src/utils/orpc.ts.hbs +73 -67
  11. package/templates/api/orpc/web/solid/src/utils/orpc.ts.hbs +15 -14
  12. package/templates/api/trpc/native/utils/trpc.ts.hbs +8 -7
  13. package/templates/api/trpc/web/react/base/src/utils/trpc.ts.hbs +59 -57
  14. package/templates/auth/better-auth/convex/backend/convex/auth.ts.hbs +3 -5
  15. package/templates/auth/better-auth/convex/backend/convex/privateData.ts.hbs +13 -12
  16. package/templates/auth/better-auth/convex/native/base/lib/auth-client.ts.hbs +10 -9
  17. package/templates/auth/better-auth/convex/web/react/next/src/lib/auth-client.ts.hbs +2 -2
  18. package/templates/auth/better-auth/convex/web/react/next/src/lib/auth-server.ts.hbs +11 -9
  19. package/templates/auth/better-auth/convex/web/react/tanstack-router/src/lib/auth-client.ts.hbs +5 -4
  20. package/templates/auth/better-auth/convex/web/react/tanstack-start/src/lib/auth-server.ts.hbs +8 -7
  21. package/templates/auth/better-auth/native/base/lib/auth-client.ts.hbs +9 -8
  22. package/templates/auth/better-auth/server/base/src/index.ts.hbs +239 -235
  23. package/templates/auth/better-auth/web/nuxt/app/plugins/auth-client.ts.hbs +2 -3
  24. package/templates/auth/better-auth/web/react/base/src/lib/auth-client.ts.hbs +9 -11
  25. package/templates/auth/better-auth/web/solid/src/lib/auth-client.ts.hbs +3 -2
  26. package/templates/backend/server/elysia/src/index.ts.hbs +71 -71
  27. package/templates/backend/server/express/src/index.ts.hbs +57 -57
  28. package/templates/backend/server/fastify/src/index.ts.hbs +107 -107
  29. package/templates/backend/server/hono/src/index.ts.hbs +75 -85
  30. package/templates/base/tsconfig.json.hbs +3 -0
  31. package/templates/db/drizzle/mysql/src/index.ts.hbs +23 -30
  32. package/templates/db/drizzle/postgres/src/index.ts.hbs +6 -13
  33. package/templates/db/drizzle/sqlite/src/index.ts.hbs +11 -18
  34. package/templates/db/mongoose/mongodb/src/index.ts.hbs +3 -2
  35. package/templates/db/prisma/mongodb/prisma/schema/schema.prisma.hbs +1 -1
  36. package/templates/db/prisma/mysql/prisma/schema/schema.prisma.hbs +1 -1
  37. package/templates/db/prisma/mysql/prisma.config.ts.hbs +16 -16
  38. package/templates/db/prisma/mysql/src/index.ts.hbs +16 -15
  39. package/templates/db/prisma/postgres/prisma/schema/schema.prisma.hbs +1 -1
  40. package/templates/db/prisma/postgres/src/index.ts.hbs +10 -9
  41. package/templates/db/prisma/sqlite/prisma/schema/schema.prisma.hbs +1 -1
  42. package/templates/db/prisma/sqlite/src/index.ts.hbs +4 -7
  43. package/templates/examples/ai/native/bare/app/(drawer)/ai.tsx.hbs +2 -1
  44. package/templates/examples/ai/native/unistyles/app/(drawer)/ai.tsx.hbs +2 -1
  45. package/templates/examples/ai/native/uniwind/app/(drawer)/ai.tsx.hbs +2 -1
  46. package/templates/examples/ai/web/nuxt/app/pages/ai.vue.hbs +1 -3
  47. package/templates/examples/ai/web/react/next/src/app/ai/page.tsx.hbs +4 -3
  48. package/templates/examples/ai/web/react/react-router/src/routes/ai.tsx.hbs +2 -1
  49. package/templates/examples/ai/web/react/tanstack-router/src/routes/ai.tsx.hbs +4 -1
  50. package/templates/examples/ai/web/react/tanstack-start/src/routes/ai.tsx.hbs +4 -1
  51. package/templates/frontend/native/bare/app/_layout.tsx.hbs +4 -2
  52. package/templates/frontend/native/unistyles/app/_layout.tsx.hbs +4 -2
  53. package/templates/frontend/native/uniwind/app/_layout.tsx.hbs +4 -3
  54. package/templates/frontend/nuxt/nuxt.config.ts.hbs +6 -3
  55. package/templates/frontend/react/next/next.config.ts.hbs +9 -8
  56. package/templates/frontend/react/next/src/components/providers.tsx.hbs +4 -1
  57. package/templates/frontend/react/next/tsconfig.json.hbs +2 -2
  58. package/templates/frontend/react/react-router/src/root.tsx.hbs +3 -4
  59. package/templates/frontend/react/tanstack-router/src/main.tsx.hbs +3 -2
  60. package/templates/frontend/react/tanstack-start/src/router.tsx.hbs +100 -108
  61. package/templates/frontend/react/tanstack-start/src/routes/__root.tsx.hbs +25 -7
  62. package/templates/packages/config/tsconfig.base.json.hbs +1 -1
  63. package/templates/{deploy/alchemy → packages/env}/env.d.ts.hbs +6 -4
  64. package/templates/packages/env/package.json.hbs +7 -0
  65. package/templates/packages/env/src/native.ts.hbs +21 -0
  66. package/templates/packages/env/src/server.ts.hbs +38 -0
  67. package/templates/packages/env/src/web.ts.hbs +89 -0
  68. package/templates/packages/env/tsconfig.json.hbs +3 -0
  69. package/templates/{deploy/alchemy → packages/infra}/alchemy.run.ts.hbs +86 -82
  70. package/templates/packages/infra/package.json.hbs +10 -0
  71. package/templates/payments/polar/server/base/src/lib/payments.ts.hbs +3 -2
@@ -314,9 +314,10 @@ import { Ionicons } from "@expo/vector-icons";
314
314
  import { Container } from "@/components/container";
315
315
  import { useColorScheme } from "@/lib/use-color-scheme";
316
316
  import { NAV_THEME } from "@/lib/constants";
317
+ import { env } from "@{{projectName}}/env/native";
317
318
 
318
319
  const generateAPIUrl = (relativePath: string) => {
319
- const serverUrl = process.env.EXPO_PUBLIC_SERVER_URL;
320
+ const serverUrl = env.EXPO_PUBLIC_SERVER_URL;
320
321
  if (!serverUrl) {
321
322
  throw new Error(
322
323
  "EXPO_PUBLIC_SERVER_URL environment variable is not defined"
@@ -308,9 +308,10 @@ import { fetch as expoFetch } from "expo/fetch";
308
308
  import { Ionicons } from "@expo/vector-icons";
309
309
  import { StyleSheet, useUnistyles } from "react-native-unistyles";
310
310
  import { Container } from "@/components/container";
311
+ import { env } from "@{{projectName}}/env/native";
311
312
 
312
313
  const generateAPIUrl = (relativePath: string) => {
313
- const serverUrl = process.env.EXPO_PUBLIC_SERVER_URL;
314
+ const serverUrl = env.EXPO_PUBLIC_SERVER_URL;
314
315
  if (!serverUrl) {
315
316
  throw new Error(
316
317
  "EXPO_PUBLIC_SERVER_URL environment variable is not defined"
@@ -192,9 +192,10 @@ import { fetch as expoFetch } from "expo/fetch";
192
192
  import { Ionicons } from "@expo/vector-icons";
193
193
  import { Container } from "@/components/container";
194
194
  import { Card, useThemeColor } from "heroui-native";
195
+ import { env } from "@{{projectName}}/env/native";
195
196
 
196
197
  const generateAPIUrl = (relativePath: string) => {
197
- const serverUrl = process.env.EXPO_PUBLIC_SERVER_URL;
198
+ const serverUrl = env.EXPO_PUBLIC_SERVER_URL;
198
199
  if (!serverUrl) {
199
200
  throw new Error(
200
201
  "EXPO_PUBLIC_SERVER_URL environment variable is not defined"
@@ -6,15 +6,13 @@ import { DefaultChatTransport } from 'ai'
6
6
  import { ref } from 'vue'
7
7
 
8
8
  const config = useRuntimeConfig()
9
- const serverUrl = config.public.serverURL
10
-
11
9
  const messages: UIMessage[] = []
12
10
  const input = ref('')
13
11
 
14
12
  const chat = new Chat({
15
13
  messages,
16
14
  transport: new DefaultChatTransport({
17
- api: `${serverUrl}/ai`,
15
+ api: `${config.public.serverUrl}/ai`,
18
16
  }),
19
17
  onError(error) {
20
18
  console.error('Chat error:', error)
@@ -9,7 +9,7 @@ import {
9
9
  } from "@convex-dev/agent/react";
10
10
  import { useMutation } from "convex/react";
11
11
  import { Send, Loader2 } from "lucide-react";
12
- {{#if (eq webDeploy "alchemy")}}
12
+ {{#if (eq webDeploy "cloudflare")}}
13
13
  import dynamic from "next/dynamic";
14
14
 
15
15
  const Streamdown = dynamic(
@@ -160,7 +160,7 @@ export default function AIPage() {
160
160
  import { useChat } from "@ai-sdk/react";
161
161
  import { DefaultChatTransport } from "ai";
162
162
  import { Send } from "lucide-react";
163
- {{#if (eq webDeploy "alchemy")}}
163
+ {{#if (eq webDeploy "cloudflare")}}
164
164
  import dynamic from "next/dynamic";
165
165
 
166
166
  const Streamdown = dynamic(
@@ -181,12 +181,13 @@ import { useEffect, useRef, useState } from "react";
181
181
 
182
182
  import { Button } from "@/components/ui/button";
183
183
  import { Input } from "@/components/ui/input";
184
+ import { env } from "@{{projectName}}/env/web";
184
185
 
185
186
  export default function AIPage() {
186
187
  const [input, setInput] = useState("");
187
188
  const { messages, sendMessage, status } = useChat({
188
189
  transport: new DefaultChatTransport({
189
- api: {{#if (eq backend "self")}}"/api/ai"{{else}}`${process.env.NEXT_PUBLIC_SERVER_URL}/ai`{{/if}},
190
+ api: {{#if (eq backend "self")}}"/api/ai"{{else}}`${env.NEXT_PUBLIC_SERVER_URL}/ai`{{/if}},
190
191
  }),
191
192
  });
192
193
 
@@ -144,6 +144,7 @@ import { useChat } from "@ai-sdk/react";
144
144
  import { DefaultChatTransport } from "ai";
145
145
  import { Send } from "lucide-react";
146
146
  import { Streamdown } from "streamdown";
147
+ import { env } from "@{{projectName}}/env/web";
147
148
 
148
149
  import { Button } from "@/components/ui/button";
149
150
  import { Input } from "@/components/ui/input";
@@ -152,7 +153,7 @@ const AI: React.FC = () => {
152
153
  const [input, setInput] = useState("");
153
154
  const { messages, sendMessage, status } = useChat({
154
155
  transport: new DefaultChatTransport({
155
- api: `${import.meta.env.VITE_SERVER_URL}/ai`,
156
+ api: `${env.VITE_SERVER_URL}/ai`,
156
157
  }),
157
158
  });
158
159
 
@@ -150,6 +150,9 @@ import { Button } from "@/components/ui/button";
150
150
  import { Send } from "lucide-react";
151
151
  import { useRef, useEffect, useState } from "react";
152
152
  import { Streamdown } from "streamdown";
153
+ {{#unless (eq backend "self")}}
154
+ import { env } from "@{{projectName}}/env/web";
155
+ {{/unless}}
153
156
 
154
157
  export const Route = createFileRoute("/ai")({
155
158
  component: RouteComponent,
@@ -159,7 +162,7 @@ function RouteComponent() {
159
162
  const [input, setInput] = useState("");
160
163
  const { messages, sendMessage, status } = useChat({
161
164
  transport: new DefaultChatTransport({
162
- api: {{#if (eq backend "self")}}"/api/ai"{{else}}`${import.meta.env.VITE_SERVER_URL}/ai`{{/if}},
165
+ api: {{#if (eq backend "self")}}"/api/ai"{{else}}`${env.VITE_SERVER_URL}/ai`{{/if}},
163
166
  }),
164
167
  });
165
168
 
@@ -148,6 +148,9 @@ import { DefaultChatTransport } from "ai";
148
148
  import { Send } from "lucide-react";
149
149
  import { useRef, useEffect, useState } from "react";
150
150
  import { Streamdown } from "streamdown";
151
+ {{#unless (eq backend "self")}}
152
+ import { env } from "@{{projectName}}/env/web";
153
+ {{/unless}}
151
154
 
152
155
  import { Button } from "@/components/ui/button";
153
156
  import { Input } from "@/components/ui/input";
@@ -160,7 +163,7 @@ function RouteComponent() {
160
163
  const [input, setInput] = useState("");
161
164
  const { messages, sendMessage, status } = useChat({
162
165
  transport: new DefaultChatTransport({
163
- api: {{#if (eq backend "self")}}"/api/ai"{{else}}`${import.meta.env.VITE_SERVER_URL}/ai`{{/if}},
166
+ api: {{#if (eq backend "self")}}"/api/ai"{{else}}`${env.VITE_SERVER_URL}/ai`{{/if}},
164
167
  }),
165
168
  });
166
169
 
@@ -7,8 +7,10 @@ import "@/polyfills";
7
7
  import { ConvexReactClient } from "convex/react";
8
8
  import { ConvexBetterAuthProvider } from "@convex-dev/better-auth/react";
9
9
  import { authClient } from "@/lib/auth-client";
10
+ import { env } from "@{{projectName}}/env/native";
10
11
  {{else}}
11
12
  import { ConvexProvider, ConvexReactClient } from "convex/react";
13
+ import { env } from "@{{projectName}}/env/native";
12
14
  {{/if}}
13
15
  {{#if (eq auth "clerk")}}
14
16
  import { ClerkProvider, useAuth } from "@clerk/clerk-expo";
@@ -56,7 +58,7 @@ export const unstable_settings = {
56
58
  };
57
59
 
58
60
  {{#if (eq backend "convex")}}
59
- const convex = new ConvexReactClient(process.env.EXPO_PUBLIC_CONVEX_URL!, {
61
+ const convex = new ConvexReactClient(env.EXPO_PUBLIC_CONVEX_URL, {
60
62
  unsavedChangesWarning: false,
61
63
  });
62
64
  {{/if}}
@@ -94,7 +96,7 @@ export default function RootLayout() {
94
96
  <>
95
97
  {{#if (eq backend "convex")}}
96
98
  {{#if (eq auth "clerk")}}
97
- <ClerkProvider tokenCache={tokenCache} publishableKey={process.env.EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY}>
99
+ <ClerkProvider tokenCache={tokenCache} publishableKey={env.EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY}>
98
100
  <ConvexProviderWithClerk client={convex} useAuth={useAuth}>
99
101
  <ThemeProvider value={isDarkColorScheme ? DARK_THEME : LIGHT_THEME}>
100
102
  <StatusBar style={isDarkColorScheme ? "light" : "dark"} />
@@ -12,8 +12,10 @@ import { queryClient } from "@/utils/orpc";
12
12
  import { ConvexReactClient } from "convex/react";
13
13
  import { ConvexBetterAuthProvider } from "@convex-dev/better-auth/react";
14
14
  import { authClient } from "@/lib/auth-client";
15
+ import { env } from "@{{projectName}}/env/native";
15
16
  {{else}}
16
17
  import { ConvexProvider, ConvexReactClient } from "convex/react";
18
+ import { env } from "@{{projectName}}/env/native";
17
19
  {{/if}}
18
20
  {{#if (eq auth "clerk")}}
19
21
  import { ClerkProvider, useAuth } from "@clerk/clerk-expo";
@@ -35,7 +37,7 @@ export const unstable_settings = {
35
37
  };
36
38
 
37
39
  {{#if (eq backend "convex")}}
38
- const convex = new ConvexReactClient(process.env.EXPO_PUBLIC_CONVEX_URL || "", {
40
+ const convex = new ConvexReactClient(env.EXPO_PUBLIC_CONVEX_URL, {
39
41
  unsavedChangesWarning: false,
40
42
  });
41
43
  {{/if}}
@@ -48,7 +50,7 @@ export default function RootLayout() {
48
50
  {{#if (eq auth "clerk")}}
49
51
  <ClerkProvider
50
52
  tokenCache={tokenCache}
51
- publishableKey={process.env.EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY}
53
+ publishableKey={env.EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY}
52
54
  >
53
55
  <ConvexProviderWithClerk client={convex} useAuth={useAuth}>
54
56
  <GestureHandlerRootView style=\{{ flex: 1 }}>
@@ -9,8 +9,10 @@ import "@/global.css";
9
9
  import { ConvexReactClient } from "convex/react";
10
10
  import { ConvexBetterAuthProvider } from "@convex-dev/better-auth/react";
11
11
  import { authClient } from "@/lib/auth-client";
12
+ import { env } from "@{{projectName}}/env/native";
12
13
  {{else}}
13
14
  import { ConvexProvider, ConvexReactClient } from "convex/react";
15
+ import { env } from "@{{projectName}}/env/native";
14
16
  {{/if}}
15
17
 
16
18
  {{#if (eq auth "clerk")}}
@@ -42,8 +44,7 @@ export const unstable_settings = {
42
44
  };
43
45
 
44
46
  {{#if (eq backend "convex")}}
45
- const convexUrl = process.env.EXPO_PUBLIC_CONVEX_URL || "";
46
- const convex = new ConvexReactClient(convexUrl, {
47
+ const convex = new ConvexReactClient(env.EXPO_PUBLIC_CONVEX_URL, {
47
48
  unsavedChangesWarning: false,
48
49
  });
49
50
  {{/if}}
@@ -64,7 +65,7 @@ export default function Layout() {
64
65
  return (
65
66
  {{#if (eq backend "convex")}}
66
67
  {{#if (eq auth "clerk")}}
67
- <ClerkProvider tokenCache={tokenCache} publishableKey={process.env.EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY}>
68
+ <ClerkProvider tokenCache={tokenCache} publishableKey={env.EXPO_PUBLIC_CLERK_PUBLISHABLE_KEY}>
68
69
  <ConvexProviderWithClerk client={convex} useAuth={useAuth}>
69
70
  <GestureHandlerRootView style=\{{ flex: 1 }}>
70
71
  <KeyboardProvider>
@@ -1,3 +1,5 @@
1
+ import "@{{projectName}}/env/web";
2
+
1
3
  // https://nuxt.com/docs/api/configuration/nuxt-config
2
4
  export default defineNuxtConfig({
3
5
  compatibilityDate: 'latest',
@@ -17,10 +19,11 @@ export default defineNuxtConfig({
17
19
  convex: {
18
20
  url: process.env.NUXT_PUBLIC_CONVEX_URL,
19
21
  },
20
- {{/if}}
22
+ {{else}}
21
23
  runtimeConfig: {
22
24
  public: {
23
- serverURL: process.env.NUXT_PUBLIC_SERVER_URL,
25
+ serverUrl: process.env.NUXT_PUBLIC_SERVER_URL,
24
26
  }
25
- }
27
+ },
28
+ {{/if}}
26
29
  })
@@ -1,21 +1,22 @@
1
- {{#if (eq webDeploy "alchemy")}}
1
+ import "@{{projectName}}/env/web";
2
+ {{#if (eq webDeploy "cloudflare")}}
2
3
  import { initOpenNextCloudflareForDev } from "@opennextjs/cloudflare";
3
4
  {{/if}}
4
5
  import type { NextConfig } from "next";
5
6
 
6
7
  const nextConfig: NextConfig = {
7
8
  typedRoutes: true,
8
- reactCompiler: true,
9
+ reactCompiler: true,
9
10
  {{#if (includes examples "ai")}}
10
- transpilePackages: ["shiki"],
11
- {{/if}}
12
- {{#if (eq dbSetup "turso")}}
13
- serverExternalPackages: ["libsql", "@libsql/client"],
14
- {{/if}}
11
+ transpilePackages: ["shiki"],
12
+ {{/if}}
13
+ {{#if (eq dbSetup "turso")}}
14
+ serverExternalPackages: ["libsql", "@libsql/client"],
15
+ {{/if}}
15
16
  };
16
17
 
17
18
  export default nextConfig;
18
19
 
19
- {{#if (eq webDeploy "alchemy")}}
20
+ {{#if (eq webDeploy "cloudflare")}}
20
21
  initOpenNextCloudflareForDev();
21
22
  {{/if}}
@@ -5,12 +5,15 @@
5
5
  import { useAuth } from "@clerk/nextjs";
6
6
  import { ConvexReactClient } from "convex/react";
7
7
  import { ConvexProviderWithClerk } from "convex/react-clerk";
8
+ import { env } from "@{{projectName}}/env/web";
8
9
  {{else if (eq auth "better-auth")}}
9
10
  import { ConvexReactClient } from "convex/react";
10
11
  import { ConvexBetterAuthProvider } from "@convex-dev/better-auth/react";
11
12
  import { authClient } from "@/lib/auth-client";
13
+ import { env } from "@{{projectName}}/env/web";
12
14
  {{else}}
13
15
  import { ConvexProvider, ConvexReactClient } from "convex/react";
16
+ import { env } from "@{{projectName}}/env/web";
14
17
  {{/if}}
15
18
  {{else}}
16
19
  {{#unless (eq api "none")}}
@@ -28,7 +31,7 @@ import { ThemeProvider } from "./theme-provider";
28
31
  import { Toaster } from "./ui/sonner";
29
32
 
30
33
  {{#if (eq backend "convex")}}
31
- const convex = new ConvexReactClient(process.env.NEXT_PUBLIC_CONVEX_URL!);
34
+ const convex = new ConvexReactClient(env.NEXT_PUBLIC_CONVEX_URL);
32
35
  {{/if}}
33
36
 
34
37
  export default function Providers({
@@ -21,13 +21,13 @@
21
21
  ],
22
22
  "paths": {
23
23
  "@/*": ["./src/*"]
24
- }{{#if (or (eq serverDeploy "alchemy") (eq webDeploy "alchemy"))}},
24
+ }{{#if (or (eq serverDeploy "cloudflare") (eq webDeploy "cloudflare"))}},
25
25
  "types": [
26
26
  "@cloudflare/workers-types"
27
27
  ]{{/if}}
28
28
  },
29
29
  "include": [
30
- {{#if (eq serverDeploy "alchemy")}}
30
+ {{#if (eq serverDeploy "cloudflare")}}
31
31
  "../server/env.d.ts",
32
32
  {{/if}}
33
33
  "./next-env.d.ts",
@@ -14,6 +14,7 @@ import { Toaster } from "./components/ui/sonner";
14
14
 
15
15
  {{#if (eq backend "convex")}}
16
16
  import { ConvexReactClient } from "convex/react";
17
+ import { env } from "@{{projectName}}/env/web";
17
18
  {{#if (eq auth "clerk")}}
18
19
  import { ClerkProvider, useAuth } from "@clerk/clerk-react";
19
20
  import { ConvexProviderWithClerk } from "convex/react-clerk";
@@ -63,12 +64,10 @@ export function Layout({ children }: { children: React.ReactNode }) {
63
64
 
64
65
  {{#if (eq backend "convex")}}
65
66
  export default function App() {
66
- const convex = new ConvexReactClient(
67
- import.meta.env.VITE_CONVEX_URL as string,
68
- );
67
+ const convex = new ConvexReactClient(env.VITE_CONVEX_URL);
69
68
  {{#if (eq auth "clerk")}}
70
69
  return (
71
- <ClerkProvider publishableKey={import.meta.env.VITE_CLERK_PUBLISHABLE_KEY}>
70
+ <ClerkProvider publishableKey={env.VITE_CLERK_PUBLISHABLE_KEY}>
72
71
  <ConvexProviderWithClerk client={convex} useAuth={useAuth}>
73
72
  <ThemeProvider
74
73
  attribute="class"
@@ -13,6 +13,7 @@ import { routeTree } from "./routeTree.gen";
13
13
  {{/if}}
14
14
  {{#if (eq backend "convex")}}
15
15
  import { ConvexReactClient } from "convex/react";
16
+ import { env } from "@{{projectName}}/env/web";
16
17
  {{#if (eq auth "clerk")}}
17
18
  import { ClerkProvider, useAuth } from "@clerk/clerk-react";
18
19
  import { ConvexProviderWithClerk } from "convex/react-clerk";
@@ -22,7 +23,7 @@ import { routeTree } from "./routeTree.gen";
22
23
  {{else}}
23
24
  import { ConvexProvider } from "convex/react";
24
25
  {{/if}}
25
- const convex = new ConvexReactClient(import.meta.env.VITE_CONVEX_URL as string);
26
+ const convex = new ConvexReactClient(env.VITE_CONVEX_URL);
26
27
  {{/if}}
27
28
 
28
29
  const router = createRouter({
@@ -53,7 +54,7 @@ const router = createRouter({
53
54
  {{#if (eq auth "clerk")}}
54
55
  return (
55
56
  <ClerkProvider
56
- publishableKey={import.meta.env.VITE_CLERK_PUBLISHABLE_KEY}
57
+ publishableKey={env.VITE_CLERK_PUBLISHABLE_KEY}
57
58
  >
58
59
  <ConvexProviderWithClerk client={convex} useAuth={useAuth}>
59
60
  {children}
@@ -1,152 +1,144 @@
1
1
  {{#if (eq backend "convex")}}
2
2
  import { createRouter as createTanStackRouter } from "@tanstack/react-router";
3
3
  import { QueryClient } from "@tanstack/react-query";
4
- import { routerWithQueryClient } from "@tanstack/react-router-with-query";
4
+ import { setupRouterSsrQueryIntegration } from "@tanstack/react-router-ssr-query";
5
5
  import { ConvexQueryClient } from "@convex-dev/react-query";
6
- import { ConvexProvider, ConvexReactClient } from "convex/react";
7
6
  import { routeTree } from "./routeTree.gen";
8
7
  import Loader from "./components/loader";
9
8
  import "./index.css";
9
+ import { env } from "@{{projectName}}/env/web";
10
10
  {{else}}
11
11
  import { createRouter as createTanStackRouter } from "@tanstack/react-router";
12
12
  import Loader from "./components/loader";
13
13
  import "./index.css";
14
14
  import { routeTree } from "./routeTree.gen";
15
- {{#if (eq api "trpc")}}
15
+ {{#if (eq api "trpc")}}
16
16
  import { QueryCache, QueryClient, QueryClientProvider } from "@tanstack/react-query";
17
17
  import { createTRPCClient, httpBatchLink } from "@trpc/client";
18
18
  import { createTRPCOptionsProxy } from "@trpc/tanstack-react-query";
19
19
  import { toast } from "sonner";
20
20
  import type { AppRouter } from "@{{projectName}}/api/routers/index";
21
21
  import { TRPCProvider } from "./utils/trpc";
22
- {{else if (eq api "orpc")}}
22
+ {{#unless (eq backend "self")}}
23
+ import { env } from "@{{projectName}}/env/web";
24
+ {{/unless}}
25
+ {{else if (eq api "orpc")}}
23
26
  import { QueryClientProvider } from "@tanstack/react-query";
24
27
  import { orpc, queryClient } from "./utils/orpc";
25
- {{/if}}
28
+ {{/if}}
26
29
  {{/if}}
27
30
 
28
31
  {{#if (eq backend "convex")}}
29
32
  export function getRouter() {
30
- const CONVEX_URL = (import.meta as any).env.VITE_CONVEX_URL!;
31
- if (!CONVEX_URL) {
32
- console.error("missing envar VITE_CONVEX_URL");
33
- }
34
- const convex = new ConvexReactClient(CONVEX_URL, {
35
- unsavedChangesWarning: false,
36
- });
33
+ const convexUrl = env.VITE_CONVEX_URL;
34
+ if (!convexUrl) {
35
+ throw new Error("VITE_CONVEX_URL is not set");
36
+ }
37
+
38
+ const convexQueryClient = new ConvexQueryClient(convexUrl);
39
+
40
+ const queryClient: QueryClient = new QueryClient({
41
+ defaultOptions: {
42
+ queries: {
43
+ queryKeyHashFn: convexQueryClient.hashFn(),
44
+ queryFn: convexQueryClient.queryFn(),
45
+ },
46
+ },
47
+ });
48
+ convexQueryClient.connect(queryClient);
37
49
 
38
- {{#if (eq auth "better-auth")}}
39
- const convexQueryClient = new ConvexQueryClient(convex, {
40
- expectAuth: true,
41
- });
42
- {{else}}
43
- const convexQueryClient = new ConvexQueryClient(convex);
44
- {{/if}}
50
+ const router = createTanStackRouter({
51
+ routeTree,
52
+ defaultPreload: "intent",
53
+ defaultPendingComponent: () => <Loader />,
54
+ defaultNotFoundComponent: () => <div>Not Found</div>,
55
+ context: { queryClient, convexQueryClient },
56
+ });
45
57
 
46
- const queryClient: QueryClient = new QueryClient({
47
- defaultOptions: {
48
- queries: {
49
- queryKeyHashFn: convexQueryClient.hashFn(),
50
- queryFn: convexQueryClient.queryFn(),
51
- },
52
- },
53
- });
54
- convexQueryClient.connect(queryClient);
58
+ setupRouterSsrQueryIntegration({
59
+ router,
60
+ queryClient,
61
+ });
55
62
 
56
- const router = routerWithQueryClient(
57
- createTanStackRouter({
58
- routeTree,
59
- defaultPreload: "intent",
60
- defaultPendingComponent: () => <Loader />,
61
- defaultNotFoundComponent: () => <div>Not Found</div>,
62
- context: { queryClient, convexClient: convex, convexQueryClient },
63
- Wrap: ({ children }) => (
64
- <ConvexProvider client={convexQueryClient.convexClient}>
65
- {children}
66
- </ConvexProvider>
67
- ),
68
- }),
69
- queryClient,
70
- );
71
- return router;
63
+ return router;
72
64
  }
73
65
  {{else}}
74
- {{#if (eq api "trpc")}}
66
+ {{#if (eq api "trpc")}}
75
67
  export const queryClient = new QueryClient({
76
- queryCache: new QueryCache({
77
- onError: (error, query) => {
78
- toast.error(error.message, {
79
- action: {
80
- label: "retry",
81
- onClick: query.invalidate,
82
- },
83
- });
84
- },
85
- }),
86
- defaultOptions: { queries: { staleTime: 60 * 1000 } },
68
+ queryCache: new QueryCache({
69
+ onError: (error, query) => {
70
+ toast.error(error.message, {
71
+ action: {
72
+ label: "retry",
73
+ onClick: query.invalidate,
74
+ },
75
+ });
76
+ },
77
+ }),
78
+ defaultOptions: { queries: { staleTime: 60 * 1000 } },
87
79
  });
88
80
 
89
81
  const trpcClient = createTRPCClient<AppRouter>({
90
- links: [
91
- httpBatchLink({
92
- url: {{#if (eq backend "self")}}"/api/trpc"{{else}}`${import.meta.env.VITE_SERVER_URL}/trpc`{{/if}},
93
- {{#if (eq auth "better-auth")}}
94
- fetch(url, options) {
95
- return fetch(url, {
96
- ...options,
97
- credentials: "include",
98
- });
99
- },
100
- {{/if}}
101
- }),
102
- ],
82
+ links: [
83
+ httpBatchLink({
84
+ url: {{#if (eq backend "self")}}"/api/trpc"{{else}}`${env.VITE_SERVER_URL}/trpc`{{/if}},
85
+ {{#if (eq auth "better-auth")}}
86
+ fetch(url, options) {
87
+ return fetch(url, {
88
+ ...options,
89
+ credentials: "include",
90
+ });
91
+ },
92
+ {{/if}}
93
+ }),
94
+ ],
103
95
  });
104
96
 
105
97
  const trpc = createTRPCOptionsProxy({
106
- client: trpcClient,
107
- queryClient: queryClient,
98
+ client: trpcClient,
99
+ queryClient: queryClient,
108
100
  });
109
- {{else if (eq api "orpc")}}
110
- {{/if}}
101
+ {{else if (eq api "orpc")}}
102
+ {{/if}}
111
103
 
112
104
  export const getRouter = () => {
113
- const router = createTanStackRouter({
114
- routeTree,
115
- scrollRestoration: true,
116
- defaultPreloadStaleTime: 0,
117
- {{#if (eq api "trpc")}}
118
- context: { trpc, queryClient },
119
- {{else if (eq api "orpc")}}
120
- context: { orpc, queryClient },
121
- {{else}}
122
- context: {},
123
- {{/if}}
124
- defaultPendingComponent: () => <Loader />,
125
- defaultNotFoundComponent: () => <div>Not Found</div>,
126
- {{#if (eq api "trpc")}}
127
- Wrap: ({ children }) => (
128
- <QueryClientProvider client={queryClient}>
129
- <TRPCProvider trpcClient={trpcClient} queryClient={queryClient}>
130
- {children}
131
- </TRPCProvider>
132
- </QueryClientProvider>
133
- ),
134
- {{else if (eq api "orpc")}}
135
- Wrap: ({ children }) => (
136
- <QueryClientProvider client={queryClient}>
137
- {children}
138
- </QueryClientProvider>
139
- ),
140
- {{else}}
141
- Wrap: ({ children }) => <>{children}</>,
142
- {{/if}}
143
- });
144
- return router;
105
+ const router = createTanStackRouter({
106
+ routeTree,
107
+ scrollRestoration: true,
108
+ defaultPreloadStaleTime: 0,
109
+ {{#if (eq api "trpc")}}
110
+ context: { trpc, queryClient },
111
+ {{else if (eq api "orpc")}}
112
+ context: { orpc, queryClient },
113
+ {{else}}
114
+ context: {},
115
+ {{/if}}
116
+ defaultPendingComponent: () => <Loader />,
117
+ defaultNotFoundComponent: () => <div>Not Found</div>,
118
+ {{#if (eq api "trpc")}}
119
+ Wrap: ({ children }) => (
120
+ <QueryClientProvider client={queryClient}>
121
+ <TRPCProvider trpcClient={trpcClient} queryClient={queryClient}>
122
+ {children}
123
+ </TRPCProvider>
124
+ </QueryClientProvider>
125
+ ),
126
+ {{else if (eq api "orpc")}}
127
+ Wrap: ({ children }) => (
128
+ <QueryClientProvider client={queryClient}>
129
+ {children}
130
+ </QueryClientProvider>
131
+ ),
132
+ {{else}}
133
+ Wrap: ({ children }) => <>{children}</>,
134
+ {{/if}}
135
+ });
136
+ return router;
145
137
  };
146
138
  {{/if}}
147
139
 
148
140
  declare module "@tanstack/react-router" {
149
- interface Register {
150
- router: ReturnType<typeof getRouter>;
151
- }
141
+ interface Register {
142
+ router: ReturnType<typeof getRouter>;
143
+ }
152
144
  }