create-tsrouter-app 0.6.8 → 0.6.10

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.
@@ -251,7 +251,10 @@ export async function createApp(options, { silent = false, environment, }) {
251
251
  if (!options.tailwind) {
252
252
  await copyFiles(templateDirBase, ['./src/App.css']);
253
253
  }
254
- await templateFile(templateDirBase, './vite.config.js.ejs');
254
+ // Don't create a vite.config.js file if we are building a Start app
255
+ if (!isAddOnEnabled('start')) {
256
+ await templateFile(templateDirBase, './vite.config.js.ejs');
257
+ }
255
258
  await templateFile(templateDirBase, './src/styles.css.ejs');
256
259
  copyFiles(templateDirBase, ['./src/logo.svg']);
257
260
  if (options.toolchain === 'biome') {
@@ -436,7 +439,7 @@ ${environment.getErrors().join('\n')}`;
436
439
  if (options.packageManager === 'deno') {
437
440
  startCommand = `deno ${isAddOnEnabled('start') ? 'task dev' : 'start'}`;
438
441
  }
439
- outro(`Created your new TanStack app in '${basename(targetDir)}'.
442
+ outro(`Created your TanStack app in '${basename(targetDir)}'.
440
443
 
441
444
  Use the following commands to start your app:
442
445
  % cd ${options.projectName}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-tsrouter-app",
3
- "version": "0.6.8",
3
+ "version": "0.6.10",
4
4
  "description": "Tanstack Application Builder",
5
5
  "bin": "./dist/index.js",
6
6
  "type": "module",
package/src/create-app.ts CHANGED
@@ -385,7 +385,12 @@ export async function createApp(
385
385
  if (!options.tailwind) {
386
386
  await copyFiles(templateDirBase, ['./src/App.css'])
387
387
  }
388
- await templateFile(templateDirBase, './vite.config.js.ejs')
388
+
389
+ // Don't create a vite.config.js file if we are building a Start app
390
+ if (!isAddOnEnabled('start')) {
391
+ await templateFile(templateDirBase, './vite.config.js.ejs')
392
+ }
393
+
389
394
  await templateFile(templateDirBase, './src/styles.css.ejs')
390
395
 
391
396
  copyFiles(templateDirBase, ['./src/logo.svg'])
@@ -707,7 +712,7 @@ ${environment.getErrors().join('\n')}`
707
712
  startCommand = `deno ${isAddOnEnabled('start') ? 'task dev' : 'start'}`
708
713
  }
709
714
 
710
- outro(`Created your new TanStack app in '${basename(targetDir)}'.
715
+ outro(`Created your TanStack app in '${basename(targetDir)}'.
711
716
 
712
717
  Use the following commands to start your app:
713
718
  % cd ${options.projectName}
@@ -7,6 +7,7 @@ export function SubscribeButton({ label }: { label: string }) {
7
7
  <form.Subscribe selector={(state) => state.isSubmitting}>
8
8
  {(isSubmitting) => (
9
9
  <button
10
+ type="submit"
10
11
  disabled={isSubmitting}
11
12
  className="px-6 py-2 bg-indigo-600 text-white rounded-md hover:bg-indigo-700 focus:outline-none focus:ring-2 focus:ring-indigo-500 focus:ring-offset-2 transition-colors disabled:opacity-50"
12
13
  >
@@ -61,10 +61,9 @@ function AddressForm() {
61
61
  }}
62
62
  className="space-y-6"
63
63
  >
64
- <form.AppField
65
- name="fullName"
66
- children={(field) => <field.TextField label="Full Name" />}
67
- />
64
+ <form.AppField name="fullName">
65
+ {(field) => <field.TextField label="Full Name" />}
66
+ </form.AppField>
68
67
 
69
68
  <form.AppField
70
69
  name="email"
@@ -79,8 +78,9 @@ function AddressForm() {
79
78
  return undefined
80
79
  },
81
80
  }}
82
- children={(field) => <field.TextField label="Email" />}
83
- />
81
+ >
82
+ {(field) => <field.TextField label="Email" />}
83
+ </form.AppField>
84
84
 
85
85
  <form.AppField
86
86
  name="address.street"
@@ -92,8 +92,9 @@ function AddressForm() {
92
92
  return undefined
93
93
  },
94
94
  }}
95
- children={(field) => <field.TextField label="Street Address" />}
96
- />
95
+ >
96
+ {(field) => <field.TextField label="Street Address" />}
97
+ </form.AppField>
97
98
 
98
99
  <div className="grid grid-cols-1 md:grid-cols-3 gap-4">
99
100
  <form.AppField
@@ -106,8 +107,9 @@ function AddressForm() {
106
107
  return undefined
107
108
  },
108
109
  }}
109
- children={(field) => <field.TextField label="City" />}
110
- />
110
+ >
111
+ {(field) => <field.TextField label="City" />}
112
+ </form.AppField>
111
113
  <form.AppField
112
114
  name="address.state"
113
115
  validators={{
@@ -118,8 +120,9 @@ function AddressForm() {
118
120
  return undefined
119
121
  },
120
122
  }}
121
- children={(field) => <field.TextField label="State" />}
122
- />
123
+ >
124
+ {(field) => <field.TextField label="State" />}
125
+ </form.AppField>
123
126
  <form.AppField
124
127
  name="address.zipCode"
125
128
  validators={{
@@ -133,8 +136,9 @@ function AddressForm() {
133
136
  return undefined
134
137
  },
135
138
  }}
136
- children={(field) => <field.TextField label="Zip Code" />}
137
- />
139
+ >
140
+ {(field) => <field.TextField label="Zip Code" />}
141
+ </form.AppField>
138
142
  </div>
139
143
 
140
144
  <form.AppField
@@ -147,7 +151,8 @@ function AddressForm() {
147
151
  return undefined
148
152
  },
149
153
  }}
150
- children={(field) => (
154
+ >
155
+ {(field) => (
151
156
  <field.Select label="Country">
152
157
  <option value="">Select a country</option>
153
158
  <option value="US">United States</option>
@@ -159,7 +164,7 @@ function AddressForm() {
159
164
  <option value="JP">Japan</option>
160
165
  </field.Select>
161
166
  )}
162
- />
167
+ </form.AppField>
163
168
 
164
169
  <form.AppField
165
170
  name="phone"
@@ -178,10 +183,11 @@ function AddressForm() {
178
183
  return undefined
179
184
  },
180
185
  }}
181
- children={(field) => (
186
+ >
187
+ {(field) => (
182
188
  <field.TextField label="Phone" placeholder="123-456-7890" />
183
189
  )}
184
- />
190
+ </form.AppField>
185
191
 
186
192
  <div className="flex justify-end">
187
193
  <form.AppForm>
@@ -194,6 +200,7 @@ function AddressForm() {
194
200
  )
195
201
  }
196
202
 
203
+
197
204
  <% if (codeRouter) { %>
198
205
  export default (parentRoute: RootRoute) => createRoute({
199
206
  path: '/demo/form',
@@ -49,15 +49,13 @@ function SimpleForm() {
49
49
  }}
50
50
  className="space-y-6"
51
51
  >
52
- <form.AppField
53
- name="title"
54
- children={(field) => <field.TextField label="Title" />}
55
- />
52
+ <form.AppField name="title">
53
+ {(field) => <field.TextField label="Title" />}
54
+ </form.AppField>
56
55
 
57
- <form.AppField
58
- name="description"
59
- children={(field) => <field.TextArea label="Description" />}
60
- />
56
+ <form.AppField name="description">
57
+ {(field) => <field.TextArea label="Description" />}
58
+ </form.AppField>
61
59
 
62
60
  <div className="flex justify-end">
63
61
  <form.AppForm>
@@ -1,5 +1,7 @@
1
1
  import { defineConfig } from '@tanstack/react-start/config'
2
- import viteTsConfigPaths from 'vite-tsconfig-paths'
2
+ import viteTsConfigPaths from 'vite-tsconfig-paths'<% if (tailwind) { %>
3
+ import tailwindcss from "@tailwindcss/vite"
4
+ <% } %>
3
5
 
4
6
  export default defineConfig({
5
7
  tsr: {
@@ -11,6 +13,7 @@ export default defineConfig({
11
13
  viteTsConfigPaths({
12
14
  projects: ['./tsconfig.json'],
13
15
  }),
16
+ <% if (tailwind) { %>tailwindcss(),<% } %>
14
17
  ],
15
18
  },
16
19
  })
@@ -2,8 +2,11 @@ import { createRouter as createTanstackRouter } from '@tanstack/react-router'<%
2
2
  import * as Sentry from '@sentry/react'
3
3
  import * as SentryServer from '@sentry/node'
4
4
  import { createIsomorphicFn } from '@tanstack/react-start'
5
+ <% } %><% if (addOnEnabled['tanstack-query']) { %>
6
+ import { routerWithQueryClient } from '@tanstack/react-router-with-query'
7
+ import * as TanstackQuery from './integrations/tanstack-query/root-provider'
5
8
  <% } %>
6
-
9
+
7
10
  // Import the generated route tree
8
11
  import { routeTree } from './routeTree.gen'
9
12
 
@@ -11,16 +14,27 @@ import './styles.css'
11
14
 
12
15
  // Create a new router instance
13
16
  export const createRouter = () => {
17
+ <% if (addOnEnabled['tanstack-query']) { %>
18
+ const router = routerWithQueryClient(createTanstackRouter({
19
+ routeTree,
20
+ context: {
21
+ <% if (addOnEnabled['tanstack-query']) { %>
22
+ ...TanstackQuery.getContext(),
23
+ <% } %>
24
+ },
25
+ scrollRestoration: true,
26
+ }), TanstackQuery.getContext().queryClient)
27
+ <% } else { %>
14
28
  const router = createTanstackRouter({
15
29
  routeTree,
16
30
  scrollRestoration: true,
17
31
  })
32
+ <% } %>
18
33
  return router
19
34
  }
20
35
 
21
- const router = createRouter()
22
-
23
36
  <% if (addOnEnabled.sentry) { %>
37
+ const router = createRouter()
24
38
  createIsomorphicFn().server(() => {
25
39
  SentryServer.init({
26
40
  dsn: import.meta.env.VITE_SENTRY_DSN,
@@ -44,8 +58,6 @@ const router = createRouter()
44
58
  })()
45
59
  <% } %>
46
60
 
47
-
48
-
49
61
  // Register the router instance for type safety
50
62
  declare module '@tanstack/react-router' {
51
63
  interface Register {
@@ -0,0 +1,11 @@
1
+ import { createAPIFileRoute } from '@tanstack/react-start/api'
2
+
3
+ export const APIRoute = createAPIFileRoute('/demo/start/api/names')({
4
+ GET: async ({ request }) => {
5
+ return new Response(JSON.stringify(['Alice', 'Bob', 'Charlie']), {
6
+ headers: {
7
+ 'Content-Type': 'application/json',
8
+ },
9
+ })
10
+ },
11
+ })
@@ -0,0 +1,33 @@
1
+ <% if (addOnEnabled['react-query']) { %>
2
+ import { useQuery } from '@tanstack/react-query'
3
+ <% } else { %>
4
+ import { useEffect, useState } from 'react'
5
+ <% } %>
6
+ import { createFileRoute } from '@tanstack/react-router'
7
+
8
+ function getNames() {
9
+ return fetch('/api/demo-names').then((res) => res.json())
10
+ }
11
+
12
+ export const Route = createFileRoute('/demo/start/api-request')({
13
+ component: Home,
14
+ })
15
+
16
+ function Home() {
17
+ <% if (addOnEnabled['react-query']) { %>
18
+ const { data: names = [] } = useQuery({
19
+ queryKey: ['names'],
20
+ queryFn: getNames,
21
+ })
22
+ <% } else { %>
23
+ const [names, setNames] = useState<Array<string>>([])
24
+ useEffect(() => {
25
+ getNames().then(setNames)
26
+ }, [])
27
+ <% } %>
28
+ return (
29
+ <div className="p-4">
30
+ <div>{names.join(', ')}</div>
31
+ </div>
32
+ )
33
+ }
@@ -1,4 +1,4 @@
1
- import * as fs from 'fs'
1
+ import * as fs from 'node:fs'
2
2
  import { createFileRoute, useRouter } from '@tanstack/react-router'
3
3
  import { createServerFn } from '@tanstack/react-start'
4
4
 
@@ -35,6 +35,7 @@ function Home() {
35
35
  return (
36
36
  <div className="p-4">
37
37
  <button
38
+ type="button"
38
39
  onClick={() => {
39
40
  updateCount({ data: 1 }).then(() => {
40
41
  router.invalidate()
@@ -9,6 +9,10 @@
9
9
  {
10
10
  "url": "/demo/start/server-funcs",
11
11
  "name": "Start - Server Functions"
12
+ },
13
+ {
14
+ "url": "/demo/start/api-request",
15
+ "name": "Start - API Request"
12
16
  }
13
17
  ]
14
18
  }
@@ -5,6 +5,7 @@
5
5
  "start": "vinxi start"
6
6
  },
7
7
  "dependencies": {
8
+ "@tanstack/react-router-with-query": "^1.114.3",
8
9
  "@tailwindcss/postcss": "^4.0.7",
9
10
  "@tanstack/react-start": "^1.114.3",
10
11
  "postcss": "^8.5.2",
@@ -15,11 +15,13 @@ export default function Header() {
15
15
  <div className="px-2 font-bold"><Link to="<%= route.url %>"><%= route.name %></Link></div>
16
16
  <% } } %>
17
17
  </nav>
18
+ <% if (integrations.filter(i => i.type === 'header-user').length > 0) { %>
18
19
  <div>
19
20
  <% for(const integration of integrations.filter(i => i.type === 'header-user')) { %>
20
21
  <<%= integration.name %> />
21
22
  <% } %>
22
- </div>
23
+ </div>
24
+ <% } %>
23
25
  </header>
24
26
  )
25
27
  }
@@ -3,7 +3,7 @@ import viteReact from "@vitejs/plugin-react";<% if (tailwind) { %>
3
3
  import tailwindcss from "@tailwindcss/vite";
4
4
  <% } %><%if (fileRouter) { %>
5
5
  import { TanStackRouterVite } from "@tanstack/router-plugin/vite";<% } %><% if (addOnEnabled['module-federation']) { %>
6
- import {federation} from "@module-federation/vite";<% } %><% if (addOnEnabled.shadcn) { %>
6
+ import { federation } from "@module-federation/vite";<% } %><% if (addOnEnabled.shadcn) { %>
7
7
  import { resolve } from "node:path";<% } %><% if (addOnEnabled['module-federation']) { %>
8
8
  import federationConfig from "./module-federation.config.js";
9
9
  <% } %>
@@ -57,7 +57,7 @@ export const Route = createRootRoute({
57
57
  <% if (addOnEnabled.start) { %>
58
58
  function RootDocument({ children }: { children: React.ReactNode }) {
59
59
  return (
60
- <html>
60
+ <html lang="en">
61
61
  <head>
62
62
  <HeadContent />
63
63
  </head>
@@ -132,7 +132,7 @@ Here is an example layout that includes a header:
132
132
 
133
133
  ```tsx
134
134
  import { Outlet, createRootRoute } from '@tanstack/solid-router'
135
- import { TanStackRouterDevtools } from '@tanstack/router-devtools'
135
+ import { TanStackRouterDevtools } from '@tanstack/solid-router-devtools'
136
136
 
137
137
  import { Link } from "@tanstack/solid-router";
138
138
 
@@ -10,7 +10,7 @@
10
10
  },
11
11
  "dependencies": {
12
12
  "@tanstack/solid-router": "^1.110.0",
13
- "@tanstack/router-devtools": "^1.109.2",
13
+ "@tanstack/solid-router-devtools": "^1.109.2",
14
14
  "@tanstack/router-plugin": "^1.109.2",
15
15
  "solid-js": "^1.9.4"
16
16
  },
@@ -5,7 +5,7 @@ import {
5
5
  createRoute,
6
6
  createRouter,
7
7
  } from "@tanstack/solid-router";
8
- // import { TanStackRouterDevtools } from "@tanstack/router-devtools";
8
+ import { TanStackRouterDevtools } from "@tanstack/solid-router-devtools";
9
9
  import { render } from 'solid-js/web'
10
10
  <% for(const route of routes) { %>import <%= route.name %> from "<%= route.path %>";
11
11
  <% } %><% if (routes.length > 0) { %>
@@ -26,7 +26,7 @@ const rootRoute = createRootRoute({
26
26
  <% } %>
27
27
  <% if (routes.length > 0) { %><Header /><% } %>
28
28
  <Outlet />
29
- {/* <TanStackRouterDevtools /> */}
29
+ <TanStackRouterDevtools />
30
30
  <% for(const integration of integrations.filter(i => i.type === 'layout')) { %>
31
31
  <<%= integration.name %> />
32
32
  <% } %>
@@ -1,5 +1,5 @@
1
1
  import { Outlet, createRootRouteWithContext } from '@tanstack/solid-router'
2
- // import { TanStackRouterDevtools } from '@tanstack/router-devtools'<% for(const integration of integrations.filter(i => i.type === 'layout' || i.type === 'provider')) { %>
2
+ import { TanStackRouterDevtools } from '@tanstack/solid-router-devtools'<% for(const integration of integrations.filter(i => i.type === 'layout' || i.type === 'provider')) { %>
3
3
  import <%= integration.name %> from "../<%= integration.path %>";
4
4
  <% } %>
5
5
  <% if (addOnEnabled['solid-ui']) { %>