create-better-t-stack 2.2.4 → 2.3.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 (47) hide show
  1. package/dist/index.js +21 -29
  2. package/package.json +1 -1
  3. package/templates/addons/turborepo/{turbo.json → turbo.json.hbs} +7 -1
  4. package/templates/api/orpc/server/base/src/lib/context.ts.hbs +0 -2
  5. package/templates/auth/web/nuxt/app/components/SignInForm.vue +0 -1
  6. package/templates/auth/web/nuxt/app/components/SignUpForm.vue +0 -1
  7. package/templates/auth/web/nuxt/app/components/UserMenu.vue +0 -1
  8. package/templates/backend/convex/packages/backend/_gitignore +2 -0
  9. package/templates/backend/convex/packages/backend/convex/README.md +90 -0
  10. package/templates/backend/convex/packages/backend/convex/healthCheck.ts +7 -0
  11. package/templates/backend/convex/packages/backend/convex/schema.ts +9 -0
  12. package/templates/backend/convex/packages/backend/convex/todos.ts +42 -0
  13. package/templates/backend/convex/packages/backend/convex/tsconfig.json +25 -0
  14. package/templates/backend/convex/packages/backend/package.json.hbs +21 -0
  15. package/templates/base/package.json +2 -1
  16. package/templates/examples/todo/web/react/react-router/src/routes/todos.tsx.hbs +178 -93
  17. package/templates/examples/todo/web/react/tanstack-router/src/routes/todos.tsx.hbs +178 -92
  18. package/templates/examples/todo/web/react/tanstack-start/src/routes/todos.tsx.hbs +119 -18
  19. package/templates/extras/pnpm-workspace.yaml +1 -0
  20. package/templates/frontend/native/app/(drawer)/index.tsx.hbs +35 -7
  21. package/templates/frontend/native/app/_layout.tsx.hbs +27 -0
  22. package/templates/frontend/react/next/package.json +0 -2
  23. package/templates/frontend/react/next/src/app/page.tsx.hbs +26 -44
  24. package/templates/frontend/react/next/src/components/providers.tsx.hbs +15 -3
  25. package/templates/frontend/react/react-router/package.json +0 -2
  26. package/templates/frontend/react/react-router/src/root.tsx.hbs +31 -11
  27. package/templates/frontend/react/react-router/src/routes/_index.tsx.hbs +28 -47
  28. package/templates/frontend/react/tanstack-router/package.json +0 -2
  29. package/templates/frontend/react/tanstack-router/src/main.tsx.hbs +18 -2
  30. package/templates/frontend/react/tanstack-router/src/routes/__root.tsx.hbs +24 -1
  31. package/templates/frontend/react/tanstack-router/src/routes/index.tsx.hbs +24 -39
  32. package/templates/frontend/react/tanstack-start/src/router.tsx.hbs +57 -13
  33. package/templates/frontend/react/tanstack-start/src/routes/__root.tsx.hbs +12 -10
  34. package/templates/frontend/react/tanstack-start/src/routes/index.tsx.hbs +31 -45
  35. /package/templates/backend/{elysia → server/elysia}/src/index.ts.hbs +0 -0
  36. /package/templates/backend/{express → server/express}/src/index.ts.hbs +0 -0
  37. /package/templates/backend/{hono → server/hono}/src/index.ts.hbs +0 -0
  38. /package/templates/backend/{next → server/next}/next-env.d.ts +0 -0
  39. /package/templates/backend/{next → server/next}/next.config.ts +0 -0
  40. /package/templates/backend/{next → server/next}/package.json +0 -0
  41. /package/templates/backend/{next → server/next}/src/app/route.ts +0 -0
  42. /package/templates/backend/{next → server/next}/src/middleware.ts +0 -0
  43. /package/templates/backend/{next → server/next}/tsconfig.json +0 -0
  44. /package/templates/backend/{server-base → server/server-base}/_gitignore +0 -0
  45. /package/templates/backend/{server-base → server/server-base}/package.json +0 -0
  46. /package/templates/backend/{server-base → server/server-base}/src/routers/index.ts.hbs +0 -0
  47. /package/templates/backend/{server-base → server/server-base}/tsconfig.json.hbs +0 -0
@@ -1,11 +1,16 @@
1
1
  "use client"
2
- {{#if (eq api "orpc")}}
2
+ {{#if (eq backend "convex")}}
3
+ import { useQuery } from "convex/react";
4
+ import { api } from "@{{projectName}}/backend/convex/_generated/api.js";
5
+ {{else}}
6
+ {{#if (eq api "orpc")}}
3
7
  import { orpc } from "@/utils/orpc";
4
- {{/if}}
5
- {{#if (eq api "trpc")}}
8
+ {{/if}}
9
+ {{#if (eq api "trpc")}}
6
10
  import { trpc } from "@/utils/trpc";
7
- {{/if}}
11
+ {{/if}}
8
12
  import { useQuery } from "@tanstack/react-query";
13
+ {{/if}}
9
14
 
10
15
  const TITLE_TEXT = `
11
16
  ██████╗ ███████╗████████╗████████╗███████╗██████╗
@@ -24,10 +29,11 @@ const TITLE_TEXT = `
24
29
  `;
25
30
 
26
31
  export default function Home() {
27
- {{#if (eq api "orpc")}}
32
+ {{#if (eq backend "convex")}}
33
+ const healthCheck = useQuery(api.healthCheck.get);
34
+ {{else if (eq api "orpc")}}
28
35
  const healthCheck = useQuery(orpc.healthCheck.queryOptions());
29
- {{/if}}
30
- {{#if (eq api "trpc")}}
36
+ {{else if (eq api "trpc")}}
31
37
  const healthCheck = useQuery(trpc.healthCheck.queryOptions());
32
38
  {{/if}}
33
39
 
@@ -38,6 +44,18 @@ export default function Home() {
38
44
  <section className="rounded-lg border p-4">
39
45
  <h2 className="mb-2 font-medium">API Status</h2>
40
46
  <div className="flex items-center gap-2">
47
+ {{#if (eq backend "convex")}}
48
+ <div
49
+ className={`h-2 w-2 rounded-full ${healthCheck === "OK" ? "bg-green-500" : healthCheck === undefined ? "bg-orange-400" : "bg-red-500"}`}
50
+ />
51
+ <span className="text-sm text-muted-foreground">
52
+ {healthCheck === undefined
53
+ ? "Checking..."
54
+ : healthCheck === "OK"
55
+ ? "Connected"
56
+ : "Error"}
57
+ </span>
58
+ {{else}}
41
59
  <div
42
60
  className={`h-2 w-2 rounded-full ${healthCheck.data ? "bg-green-500" : "bg-red-500"}`}
43
61
  />
@@ -48,46 +66,10 @@ export default function Home() {
48
66
  ? "Connected"
49
67
  : "Disconnected"}
50
68
  </span>
69
+ {{/if}}
51
70
  </div>
52
71
  </section>
53
-
54
- <section>
55
- <h2 className="mb-3 font-medium">Core Features</h2>
56
- <ul className="grid grid-cols-2 gap-3">
57
- <FeatureItem
58
- title="Type-Safe API"
59
- description="End-to-end type safety with tRPC"
60
- />
61
- <FeatureItem
62
- title="Modern React"
63
- description="TanStack Router + TanStack Query"
64
- />
65
- <FeatureItem
66
- title="Fast Backend"
67
- description="Lightweight Hono server"
68
- />
69
- <FeatureItem
70
- title="Beautiful UI"
71
- description="TailwindCSS + shadcn/ui components"
72
- />
73
- </ul>
74
- </section>
75
72
  </div>
76
73
  </div>
77
74
  );
78
75
  }
79
-
80
- function FeatureItem({
81
- title,
82
- description,
83
- }: {
84
- title: string;
85
- description: string;
86
- }) {
87
- return (
88
- <li className="border-l-2 border-primary py-1 pl-3">
89
- <h3 className="font-medium">{title}</h3>
90
- <p className="text-sm text-muted-foreground">{description}</p>
91
- </li>
92
- );
93
- }
@@ -1,14 +1,22 @@
1
1
  "use client"
2
+ {{#if (eq backend "convex")}}
3
+ import { ConvexProvider, ConvexReactClient } from "convex/react";
4
+ {{else}}
2
5
  import { QueryClientProvider } from "@tanstack/react-query";
3
- {{#if (eq api "orpc")}}
6
+ {{#if (eq api "orpc")}}
4
7
  import { orpc, ORPCContext, queryClient } from "@/utils/orpc";
5
- {{/if}}
6
- {{#if (eq api "trpc")}}
8
+ {{/if}}
9
+ {{#if (eq api "trpc")}}
7
10
  import { queryClient } from "@/utils/trpc";
11
+ {{/if}}
8
12
  {{/if}}
9
13
  import { ThemeProvider } from "./theme-provider";
10
14
  import { Toaster } from "./ui/sonner";
11
15
 
16
+ {{#if (eq backend "convex")}}
17
+ const convex = new ConvexReactClient(process.env.NEXT_PUBLIC_CONVEX_URL!);
18
+ {{/if}}
19
+
12
20
  export default function Providers({
13
21
  children,
14
22
  }: {
@@ -21,6 +29,9 @@ export default function Providers({
21
29
  enableSystem
22
30
  disableTransitionOnChange
23
31
  >
32
+ {{#if (eq backend "convex")}}
33
+ <ConvexProvider client={convex}>{children}</ConvexProvider>
34
+ {{else}}
24
35
  <QueryClientProvider client={queryClient}>
25
36
  {{#if (eq api "orpc")}}
26
37
  <ORPCContext.Provider value={orpc}>
@@ -31,6 +42,7 @@ export default function Providers({
31
42
  {children}
32
43
  {{/if}}
33
44
  </QueryClientProvider>
45
+ {{/if}}
34
46
  <Toaster richColors />
35
47
  </ThemeProvider>
36
48
  )
@@ -17,7 +17,6 @@
17
17
  "@react-router/node": "^7.4.1",
18
18
  "@react-router/serve": "^7.4.1",
19
19
  "@tanstack/react-form": "^1.2.3",
20
- "@tanstack/react-query": "^5.71.3",
21
20
  "class-variance-authority": "^0.7.1",
22
21
  "clsx": "^2.1.1",
23
22
  "isbot": "^5.1.17",
@@ -34,7 +33,6 @@
34
33
  "devDependencies": {
35
34
  "@react-router/dev": "^7.4.1",
36
35
  "@tailwindcss/vite": "^4.0.0",
37
- "@tanstack/react-query-devtools": "^5.71.3",
38
36
  "@types/node": "^20",
39
37
  "@types/react": "^19.0.1",
40
38
  "@types/react-dom": "^19.0.1",
@@ -1,5 +1,3 @@
1
- import { QueryClientProvider } from "@tanstack/react-query";
2
- import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
3
1
  import {
4
2
  isRouteErrorResponse,
5
3
  Links,
@@ -14,11 +12,17 @@ import Header from "./components/header";
14
12
  import { ThemeProvider } from "./components/theme-provider";
15
13
  import { Toaster } from "./components/ui/sonner";
16
14
 
17
- {{#if (eq api "orpc")}}
18
- import { orpc, ORPCContext, queryClient } from "./utils/orpc";
19
- {{/if}}
20
- {{#if (eq api "trpc")}}
21
- import { queryClient } from "./utils/trpc";
15
+ {{#if (eq backend "convex")}}
16
+ import { ConvexProvider, ConvexReactClient } from "convex/react";
17
+ {{else}}
18
+ import { QueryClientProvider } from "@tanstack/react-query";
19
+ import { ReactQueryDevtools } from "@tanstack/react-query-devtools";
20
+ {{#if (eq api "orpc")}}
21
+ import { orpc, ORPCContext, queryClient } from "./utils/orpc";
22
+ {{/if}}
23
+ {{#if (eq api "trpc")}}
24
+ import { queryClient } from "./utils/trpc";
25
+ {{/if}}
22
26
  {{/if}}
23
27
 
24
28
  export const links: Route.LinksFunction = () => [
@@ -52,7 +56,25 @@ export function Layout({ children }: { children: React.ReactNode }) {
52
56
  );
53
57
  }
54
58
 
55
- {{#if (eq api "orpc")}}
59
+ {{#if (eq backend "convex")}}
60
+ export default function App() {
61
+ const convex = new ConvexReactClient(
62
+ import.meta.env.VITE_CONVEX_URL as string,
63
+ );
64
+
65
+ return (
66
+ <ConvexProvider client={convex}>
67
+ <ThemeProvider defaultTheme="dark" storageKey="vite-ui-theme">
68
+ <div className="grid grid-rows-[auto_1fr] h-svh">
69
+ <Header />
70
+ <Outlet />
71
+ </div>
72
+ <Toaster richColors />
73
+ </ThemeProvider>
74
+ </ConvexProvider>
75
+ );
76
+ }
77
+ {{else if (eq api "orpc")}}
56
78
  export default function App() {
57
79
  return (
58
80
  <QueryClientProvider client={queryClient}>
@@ -69,9 +91,7 @@ export default function App() {
69
91
  </QueryClientProvider>
70
92
  );
71
93
  }
72
- {{/if}}
73
-
74
- {{#if (eq api "trpc")}}
94
+ {{else if (eq api "trpc")}}
75
95
  export default function App() {
76
96
  return (
77
97
  <QueryClientProvider client={queryClient}>
@@ -1,11 +1,16 @@
1
1
  import type { Route } from "./+types/_index";
2
- {{#if (eq api "orpc")}}
3
- import { orpc } from "@/utils/orpc";
4
- {{/if}}
5
- {{#if (eq api "trpc")}}
6
- import { trpc } from "@/utils/trpc";
7
- {{/if}}
2
+ {{#if (eq backend "convex")}}
3
+ import { useQuery } from "convex/react";
4
+ import { api } from "@{{projectName}}/backend/convex/_generated/api.js";
5
+ {{else}}
6
+ {{#if (eq api "orpc")}}
7
+ import { orpc } from "@/utils/orpc";
8
+ {{/if}}
9
+ {{#if (eq api "trpc")}}
10
+ import { trpc } from "@/utils/trpc";
11
+ {{/if}}
8
12
  import { useQuery } from "@tanstack/react-query";
13
+ {{/if}}
9
14
 
10
15
  const TITLE_TEXT = `
11
16
  ██████╗ ███████╗████████╗████████╗███████╗██████╗
@@ -28,11 +33,11 @@ export function meta({}: Route.MetaArgs) {
28
33
  }
29
34
 
30
35
  export default function Home() {
31
-
32
- {{#if (eq api "orpc")}}
36
+ {{#if (eq backend "convex")}}
37
+ const healthCheck = useQuery(api.healthCheck.get);
38
+ {{else if (eq api "orpc")}}
33
39
  const healthCheck = useQuery(orpc.healthCheck.queryOptions());
34
- {{/if}}
35
- {{#if (eq api "trpc")}}
40
+ {{else if (eq api "trpc")}}
36
41
  const healthCheck = useQuery(trpc.healthCheck.queryOptions());
37
42
  {{/if}}
38
43
 
@@ -43,6 +48,18 @@ export default function Home() {
43
48
  <section className="rounded-lg border p-4">
44
49
  <h2 className="mb-2 font-medium">API Status</h2>
45
50
  <div className="flex items-center gap-2">
51
+ {{#if (eq backend "convex")}}
52
+ <div
53
+ className={`h-2 w-2 rounded-full ${healthCheck === "OK" ? "bg-green-500" : healthCheck === undefined ? "bg-orange-400" : "bg-red-500"}`}
54
+ />
55
+ <span className="text-sm text-muted-foreground">
56
+ {healthCheck === undefined
57
+ ? "Checking..."
58
+ : healthCheck === "OK"
59
+ ? "Connected"
60
+ : "Error"}
61
+ </span>
62
+ {{else}}
46
63
  <div
47
64
  className={`h-2 w-2 rounded-full ${
48
65
  healthCheck.data ? "bg-green-500" : "bg-red-500"
@@ -55,46 +72,10 @@ export default function Home() {
55
72
  ? "Connected"
56
73
  : "Disconnected"}
57
74
  </span>
75
+ {{/if}}
58
76
  </div>
59
77
  </section>
60
-
61
- <section>
62
- <h2 className="mb-3 font-medium">Core Features</h2>
63
- <ul className="grid grid-cols-2 gap-3">
64
- <FeatureItem
65
- title="Type-Safe API"
66
- description="End-to-end type safety with tRPC"
67
- />
68
- <FeatureItem
69
- title="Modern React"
70
- description="TanStack Router + TanStack Query"
71
- />
72
- <FeatureItem
73
- title="Fast Backend"
74
- description="Lightweight Hono server"
75
- />
76
- <FeatureItem
77
- title="Beautiful UI"
78
- description="TailwindCSS + shadcn/ui components"
79
- />
80
- </ul>
81
- </section>
82
78
  </div>
83
79
  </div>
84
80
  );
85
81
  }
86
-
87
- function FeatureItem({
88
- title,
89
- description,
90
- }: {
91
- title: string;
92
- description: string;
93
- }) {
94
- return (
95
- <li className="border-l-2 border-primary py-1 pl-3">
96
- <h3 className="font-medium">{title}</h3>
97
- <p className="text-sm text-muted-foreground">{description}</p>
98
- </li>
99
- );
100
- }
@@ -11,7 +11,6 @@
11
11
  "check-types": "tsc --noEmit"
12
12
  },
13
13
  "devDependencies": {
14
- "@tanstack/react-query-devtools": "^5.69.0",
15
14
  "@tanstack/react-router-devtools": "^1.114.27",
16
15
  "@tanstack/router-plugin": "^1.114.27",
17
16
  "@types/node": "^22.13.13",
@@ -30,7 +29,6 @@
30
29
  "@radix-ui/react-slot": "^1.1.2",
31
30
  "@tanstack/react-form": "^1.0.5",
32
31
  "@tailwindcss/vite": "^4.0.15",
33
- "@tanstack/react-query": "^5.69.0",
34
32
  "@tanstack/react-router": "^1.114.25",
35
33
  "class-variance-authority": "^0.7.1",
36
34
  "clsx": "^2.1.1",
@@ -1,14 +1,20 @@
1
- import { QueryClientProvider } from "@tanstack/react-query";
2
1
  import { RouterProvider, createRouter } from "@tanstack/react-router";
3
2
  import ReactDOM from "react-dom/client";
4
3
  import Loader from "./components/loader";
5
4
  import { routeTree } from "./routeTree.gen";
6
5
  {{#if (eq api "orpc")}}
6
+ import { QueryClientProvider } from "@tanstack/react-query";
7
7
  import { orpc, queryClient } from "./utils/orpc";
8
8
  {{/if}}
9
9
  {{#if (eq api "trpc")}}
10
+ import { QueryClientProvider } from "@tanstack/react-query";
10
11
  import { queryClient, trpc } from "./utils/trpc";
11
12
  {{/if}}
13
+ {{#if (eq backend "convex")}}
14
+ import { ConvexProvider, ConvexReactClient } from "convex/react";
15
+
16
+ const convex = new ConvexReactClient(import.meta.env.VITE_CONVEX_URL as string);
17
+ {{/if}}
12
18
 
13
19
  {{#if (eq api "orpc")}}
14
20
  const router = createRouter({
@@ -36,8 +42,18 @@ const router = createRouter({
36
42
  },
37
43
  });
38
44
  {{/if}}
45
+ {{#if (eq backend "convex")}}
46
+ const router = createRouter({
47
+ routeTree,
48
+ defaultPreload: "intent",
49
+ defaultPendingComponent: () => <Loader />,
50
+ context: {},
51
+ Wrap: function WrapComponent({ children }) {
52
+ return <ConvexProvider client={convex}>{children}</ConvexProvider>;
53
+ },
54
+ });
55
+ {{/if}}
39
56
 
40
- // Register things for typesafety
41
57
  declare module "@tanstack/react-router" {
42
58
  interface Register {
43
59
  router: typeof router;
@@ -38,6 +38,9 @@ export interface RouterAppContext {
38
38
  queryClient: QueryClient;
39
39
  }
40
40
  {{/if}}
41
+ {{#if (eq backend "convex")}}
42
+ export interface RouterAppContext {}
43
+ {{/if}}
41
44
 
42
45
  export const Route = createRootRouteWithContext<RouterAppContext>()({
43
46
  component: RootComponent,
@@ -106,4 +109,24 @@ function RootComponent() {
106
109
  </>
107
110
  );
108
111
  }
109
- {{/if}}
112
+ {{/if}}
113
+ {{#if (eq backend "convex")}}
114
+ function RootComponent() {
115
+ const isFetching = useRouterState({
116
+ select: (s) => s.isLoading,
117
+ });
118
+ return (
119
+ <>
120
+ <HeadContent />
121
+ <ThemeProvider defaultTheme="dark" storageKey="vite-ui-theme">
122
+ <div className="grid grid-rows-[auto_1fr] h-svh">
123
+ <Header />
124
+ {isFetching ? <Loader /> : <Outlet />}
125
+ </div>
126
+ <Toaster richColors />
127
+ </ThemeProvider>
128
+ <TanStackRouterDevtools position="bottom-left" />
129
+ </>
130
+ );
131
+ }
132
+ {{/if}}
@@ -1,11 +1,16 @@
1
+ import { createFileRoute } from "@tanstack/react-router";
1
2
  {{#if (eq api "orpc")}}
2
3
  import { orpc } from "@/utils/orpc";
4
+ import { useQuery } from "@tanstack/react-query";
3
5
  {{/if}}
4
6
  {{#if (eq api "trpc")}}
5
7
  import { trpc } from "@/utils/trpc";
6
- {{/if}}
7
8
  import { useQuery } from "@tanstack/react-query";
8
- import { createFileRoute } from "@tanstack/react-router";
9
+ {{/if}}
10
+ {{#if (eq backend "convex")}}
11
+ import { useQuery } from "convex/react";
12
+ import { api } from "@{{ projectName }}/backend/convex/_generated/api.js";
13
+ {{/if}}
9
14
 
10
15
  export const Route = createFileRoute("/")({
11
16
  component: HomeComponent,
@@ -34,6 +39,9 @@ function HomeComponent() {
34
39
  {{#if (eq api "trpc")}}
35
40
  const healthCheck = useQuery(trpc.healthCheck.queryOptions());
36
41
  {{/if}}
42
+ {{#if (eq backend "convex")}}
43
+ const healthCheck = useQuery(api.healthCheck.get);
44
+ {{/if}}
37
45
 
38
46
  return (
39
47
  <div className="container mx-auto max-w-3xl px-4 py-2">
@@ -42,6 +50,7 @@ function HomeComponent() {
42
50
  <section className="rounded-lg border p-4">
43
51
  <h2 className="mb-2 font-medium">API Status</h2>
44
52
  <div className="flex items-center gap-2">
53
+ {{#if (or (eq api "orpc") (eq api "trpc"))}}
45
54
  <div
46
55
  className={`h-2 w-2 rounded-full ${healthCheck.data ? "bg-green-500" : "bg-red-500"}`}
47
56
  />
@@ -52,46 +61,22 @@ function HomeComponent() {
52
61
  ? "Connected"
53
62
  : "Disconnected"}
54
63
  </span>
55
- </div>
56
- </section>
57
-
58
- <section>
59
- <h2 className="mb-3 font-medium">Core Features</h2>
60
- <ul className="grid grid-cols-2 gap-3">
61
- <FeatureItem
62
- title="Type-Safe API"
63
- description="End-to-end type safety with tRPC"
64
- />
65
- <FeatureItem
66
- title="Modern React"
67
- description="TanStack Router + TanStack Query"
68
- />
69
- <FeatureItem
70
- title="Fast Backend"
71
- description="Lightweight Hono server"
72
- />
73
- <FeatureItem
74
- title="Beautiful UI"
75
- description="TailwindCSS + shadcn/ui components"
64
+ {{/if}}
65
+ {{#if (eq backend "convex")}}
66
+ <div
67
+ className={`h-2 w-2 rounded-full ${healthCheck === "OK" ? "bg-green-500" : healthCheck === undefined ? "bg-orange-400" : "bg-red-500"}`}
76
68
  />
77
- </ul>
69
+ <span className="text-sm text-muted-foreground">
70
+ {healthCheck === undefined
71
+ ? "Checking..."
72
+ : healthCheck === "OK"
73
+ ? "Connected"
74
+ : "Error"}
75
+ </span>
76
+ {{/if}}
77
+ </div>
78
78
  </section>
79
79
  </div>
80
80
  </div>
81
81
  );
82
82
  }
83
-
84
- function FeatureItem({
85
- title,
86
- description,
87
- }: {
88
- title: string;
89
- description: string;
90
- }) {
91
- return (
92
- <li className="border-l-2 border-primary py-1 pl-3">
93
- <h3 className="font-medium">{title}</h3>
94
- <p className="text-sm text-muted-foreground">{description}</p>
95
- </li>
96
- );
97
- }
@@ -1,3 +1,13 @@
1
+ {{#if (eq backend "convex")}}
2
+ import { createRouter as createTanStackRouter } from "@tanstack/react-router";
3
+ import { QueryClient } from "@tanstack/react-query";
4
+ import { routerWithQueryClient } from "@tanstack/react-router-with-query";
5
+ import { ConvexQueryClient } from "@convex-dev/react-query";
6
+ import { ConvexProvider } from "convex/react";
7
+ import { routeTree } from "./routeTree.gen";
8
+ import Loader from "./components/loader";
9
+ import "./index.css";
10
+ {{else}}
1
11
  import {
2
12
  QueryCache,
3
13
  QueryClient,
@@ -7,18 +17,56 @@ import { createRouter as createTanstackRouter } from "@tanstack/react-router";
7
17
  import Loader from "./components/loader";
8
18
  import "./index.css";
9
19
  import { routeTree } from "./routeTree.gen";
10
- {{#if (eq api "trpc")}}
20
+ {{#if (eq api "trpc")}}
11
21
  import { createTRPCClient, httpBatchLink } from "@trpc/client";
12
22
  import { createTRPCOptionsProxy } from "@trpc/tanstack-react-query";
13
23
  import { toast } from "sonner";
14
24
  import type { AppRouter } from "../../server/src/routers";
15
25
  import { TRPCProvider } from "./utils/trpc";
16
- {{/if}}
17
- {{#if (eq api "orpc")}}
26
+ {{/if}}
27
+ {{#if (eq api "orpc")}}
18
28
  import { orpc, ORPCContext, queryClient } from "./utils/orpc";
29
+ {{/if}}
19
30
  {{/if}}
20
31
 
21
- {{#if (eq api "trpc")}}
32
+ {{#if (eq backend "convex")}}
33
+ export function createRouter() {
34
+ const CONVEX_URL = (import.meta as any).env.VITE_CONVEX_URL!;
35
+ if (!CONVEX_URL) {
36
+ console.error("missing envar VITE_CONVEX_URL");
37
+ }
38
+ const convexQueryClient = new ConvexQueryClient(CONVEX_URL);
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);
49
+
50
+ const router = routerWithQueryClient(
51
+ createTanStackRouter({
52
+ routeTree,
53
+ defaultPreload: "intent",
54
+ defaultPendingComponent: () => <Loader />,
55
+ defaultNotFoundComponent: () => <div>Not Found</div>,
56
+ context: { queryClient },
57
+ Wrap: ({ children }) => (
58
+ <ConvexProvider client={convexQueryClient.convexClient}>
59
+ {children}
60
+ </ConvexProvider>
61
+ ),
62
+ }),
63
+ queryClient,
64
+ );
65
+
66
+ return router;
67
+ }
68
+ {{else}}
69
+ {{#if (eq api "trpc")}}
22
70
  export const queryClient = new QueryClient({
23
71
  queryCache: new QueryCache({
24
72
  onError: (error) => {
@@ -38,11 +86,7 @@ export const queryClient = new QueryClient({
38
86
  const trpcClient = createTRPCClient<AppRouter>({
39
87
  links: [
40
88
  httpBatchLink({
41
- {{#if (includes frontend 'next')}}
42
- url: `${process.env.NEXT_PUBLIC_SERVER_URL}/trpc`,
43
- {{else}}
44
89
  url: `${import.meta.env.VITE_SERVER_URL}/trpc`,
45
- {{/if}}
46
90
  {{#if auth}}
47
91
  fetch(url, options) {
48
92
  return fetch(url, {
@@ -59,8 +103,7 @@ const trpc = createTRPCOptionsProxy({
59
103
  client: trpcClient,
60
104
  queryClient: queryClient,
61
105
  });
62
- {{/if}}
63
-
106
+ {{/if}}
64
107
 
65
108
  export const createRouter = () => {
66
109
  const router = createTanstackRouter({
@@ -69,10 +112,10 @@ export const createRouter = () => {
69
112
  defaultPreloadStaleTime: 0,
70
113
  {{#if (eq api "trpc")}}
71
114
  context: { trpc, queryClient },
72
- {{/if}}
73
- {{#if (eq api "orpc")}}
115
+ {{/if}}
116
+ {{#if (eq api "orpc")}}
74
117
  context: { orpc, queryClient },
75
- {{/if}}
118
+ {{/if}}
76
119
  defaultPendingComponent: () => <Loader />,
77
120
  defaultNotFoundComponent: () => <div>Not Found</div>,
78
121
  Wrap: ({ children }) => (
@@ -93,6 +136,7 @@ export const createRouter = () => {
93
136
 
94
137
  return router;
95
138
  };
139
+ {{/if}}
96
140
 
97
141
  // Register the router instance for type safety
98
142
  declare module "@tanstack/react-router" {
@@ -11,26 +11,28 @@ import { TanStackRouterDevtools } from "@tanstack/react-router-devtools";
11
11
  import Header from "../components/header";
12
12
  import appCss from "../index.css?url";
13
13
  import type { QueryClient } from "@tanstack/react-query";
14
- {{#if (eq api "trpc")}}
15
- import type { TRPCOptionsProxy } from "@trpc/tanstack-react-query";
16
- import type { AppRouter } from "../../../server/src/routers";
17
- {{/if}}
18
- {{#if (eq api "orpc")}}
19
- import type { orpc } from "@/utils/orpc";
20
- {{/if}}
21
14
  import Loader from "@/components/loader";
22
15
 
23
- {{#if (eq api "trpc")}}
16
+ {{#if (eq backend "convex")}}
17
+ export interface RouterAppContext {
18
+ queryClient: QueryClient;
19
+ }
20
+ {{else}}
21
+ {{#if (eq api "trpc")}}
22
+ import type { TRPCOptionsProxy } from "@trpc/tanstack-react-query";
23
+ import type { AppRouter } from "../../../server/src/routers";
24
24
  export interface RouterAppContext {
25
25
  trpc: TRPCOptionsProxy<AppRouter>;
26
26
  queryClient: QueryClient;
27
27
  }
28
- {{/if}}
29
- {{#if (eq api "orpc")}}
28
+ {{/if}}
29
+ {{#if (eq api "orpc")}}
30
+ import type { orpc } from "@/utils/orpc";
30
31
  export interface RouterAppContext {
31
32
  orpc: typeof orpc;
32
33
  queryClient: QueryClient;
33
34
  }
35
+ {{/if}}
34
36
  {{/if}}
35
37
 
36
38
  export const Route = createRootRouteWithContext<RouterAppContext>()({