create-tsrouter-app 0.9.7 → 0.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 (48) hide show
  1. package/README.md +3 -1
  2. package/dist/create-app.js +27 -1
  3. package/dist/toolchain.js +5 -1
  4. package/package.json +1 -1
  5. package/src/create-app.ts +42 -1
  6. package/src/toolchain.ts +5 -1
  7. package/templates/react/add-on/start/assets/src/router.tsx.ejs +9 -0
  8. package/templates/react/add-on/tRPC/assets/src/integrations/trpc/init.ts +9 -0
  9. package/templates/react/add-on/tRPC/assets/src/integrations/trpc/react.ts +4 -0
  10. package/templates/react/add-on/tRPC/assets/src/integrations/trpc/router.ts +18 -0
  11. package/templates/react/add-on/tRPC/assets/src/routes/api.trpc.$.tsx +16 -0
  12. package/templates/react/add-on/tRPC/info.json +9 -0
  13. package/templates/react/add-on/tRPC/package.json +9 -0
  14. package/templates/react/add-on/tanstack-query/assets/src/integrations/tanstack-query/root-provider.tsx.ejs +70 -0
  15. package/templates/react/add-on/tanstack-query/assets/src/routes/demo.tanstack-query.tsx.ejs +16 -1
  16. package/templates/react/base/README.md.ejs +6 -3
  17. package/templates/react/base/package.eslintprettier.json +11 -0
  18. package/templates/react/base/toolchain/.prettierignore +3 -0
  19. package/templates/react/base/toolchain/eslint.config.js +5 -0
  20. package/templates/react/base/toolchain/prettier.config.js +10 -0
  21. package/templates/react/base/tsconfig.json.ejs +4 -3
  22. package/templates/react/base/vite.config.js.ejs +4 -5
  23. package/templates/react/example/tanchat/assets/public/example-guitar-flowers.jpg +0 -0
  24. package/templates/react/example/tanchat/assets/public/example-guitar-superhero.jpg +0 -0
  25. package/templates/react/example/tanchat/assets/public/example-guitar-traveling.jpg +0 -0
  26. package/templates/react/example/tanchat/assets/public/example-guitar-video-games.jpg +0 -0
  27. package/templates/react/example/tanchat/assets/src/data/example-guitars.ts +31 -21
  28. package/templates/react/example/tanchat/assets/src/routes/example.guitars/index.tsx +2 -2
  29. package/templates/react/file-router/src/routes/__root.tsx.ejs +7 -0
  30. package/templates/solid/base/README.md.ejs +15 -0
  31. package/templates/solid/base/package.eslintprettier.json +11 -0
  32. package/templates/solid/base/toolchain/.prettierignore +3 -0
  33. package/templates/solid/base/toolchain/eslint.config.js +5 -0
  34. package/templates/solid/base/toolchain/prettier.config.js +10 -0
  35. package/templates/solid/base/tsconfig.json.ejs +2 -1
  36. package/templates/solid/example/tanchat/info.json +1 -1
  37. package/tests/snapshots/cra/cr-js-npm.json +2 -2
  38. package/tests/snapshots/cra/cr-ts-npm.json +3 -3
  39. package/tests/snapshots/cra/fr-ts-npm.json +3 -3
  40. package/tests/snapshots/cra/fr-ts-tw-npm.json +3 -3
  41. package/tests/snapshots/cra/solid-cr-js-npm.json +1 -1
  42. package/tests/snapshots/cra/solid-cr-ts-npm.json +1 -1
  43. package/tests/snapshots/cra/solid-fr-ts-npm.json +1 -1
  44. package/tests/snapshots/cra/solid-fr-ts-tw-npm.json +1 -1
  45. package/templates/react/add-on/tanstack-query/assets/src/integrations/tanstack-query/root-provider.tsx +0 -15
  46. package/templates/react/example/tanchat/assets/public/example-guitar-dune.jpg +0 -0
  47. package/templates/react/example/tanchat/assets/public/example-guitar-steampunk.jpg +0 -0
  48. package/templates/react/example/tanchat/assets/public/example-guitar-underwater.jpg +0 -0
package/README.md CHANGED
@@ -46,7 +46,7 @@ Available options:
46
46
  - `--template <type>`: Choose between `file-router`, `typescript`, or `javascript`
47
47
  - `--tailwind`: Enable Tailwind CSS
48
48
  - `--package-manager`: Specify your preferred package manager (`npm`, `yarn`, `pnpm`, `bun`, or `deno`)
49
- - `--toolchain`: Specify your toolchain solution for formatting/linting (`biome`)
49
+ - `--toolchain`: Specify your toolchain solution for formatting/linting (`biome`, `eslint+prettier`)
50
50
  - `--no-git`: Do not initialize a git repository
51
51
  - `--add-ons`: Enable add-on selection or specify add-ons to install
52
52
 
@@ -102,6 +102,8 @@ Choose your preferred solution for formatting and linting either through the int
102
102
 
103
103
  Setting this flag to `biome` will configure it as your toolchain of choice, adding a `biome.json` to the root of the project. Consult the [biome documentation](https://biomejs.dev/guides/getting-started/) for further customization.
104
104
 
105
+ Setting this flag to `eslint+prettier` will configure it as your toolchain of choice, adding an `eslint.config.js` and `prettier.config.js` to the root of the project, as well as a `.prettierignore` file. Consult the [eslint documentation](https://eslint.org/docs/latest/) and [prettier documentation](https://prettier.io/docs/) for further customization.
106
+
105
107
  ## Add-ons (experimental)
106
108
 
107
109
  You can enable add-on selection:
@@ -147,6 +147,20 @@ async function createPackageJSON(environment, projectName, options, templateDir,
147
147
  },
148
148
  };
149
149
  }
150
+ if (options.toolchain === 'eslint+prettier') {
151
+ const eslintPrettierPackageJSON = JSON.parse(await environment.readFile(resolve(templateDir, 'package.eslintprettier.json'), 'utf-8'));
152
+ packageJSON = {
153
+ ...packageJSON,
154
+ scripts: {
155
+ ...packageJSON.scripts,
156
+ ...eslintPrettierPackageJSON.scripts,
157
+ },
158
+ devDependencies: {
159
+ ...packageJSON.devDependencies,
160
+ ...eslintPrettierPackageJSON.devDependencies,
161
+ },
162
+ };
163
+ }
150
164
  if (options.mode === FILE_ROUTER) {
151
165
  const frPackageJSON = JSON.parse(await environment.readFile(resolve(routerDir, 'package.fr.json'), 'utf8'));
152
166
  packageJSON = {
@@ -261,6 +275,13 @@ export async function createApp(options, { silent = false, environment, }) {
261
275
  if (options.toolchain === 'biome') {
262
276
  copyFiles(templateDirBase, ['./toolchain/biome.json'], true);
263
277
  }
278
+ if (options.toolchain === 'eslint+prettier') {
279
+ copyFiles(templateDirBase, [
280
+ './toolchain/eslint.config.js',
281
+ './toolchain/prettier.config.js',
282
+ './toolchain/.prettierignore',
283
+ ], true);
284
+ }
264
285
  // Setup reportWebVitals
265
286
  if (!isAddOnEnabled('start') && options.framework === 'react') {
266
287
  if (options.typescript) {
@@ -279,7 +300,7 @@ export async function createApp(options, { silent = false, environment, }) {
279
300
  if (options.typescript) {
280
301
  await templateFile(templateDirBase, './tsconfig.json.ejs', './tsconfig.json');
281
302
  }
282
- // Setup the package.json file, optionally with typescript, tailwind and biome
303
+ // Setup the package.json file, optionally with typescript, tailwind and formatter/linter
283
304
  await createPackageJSON(environment, options.projectName, options, templateDirBase, templateDirRouter, targetDir, options.chosenAddOns.map((addOn) => addOn.packageAdditions));
284
305
  // Copy all the asset files from the addons
285
306
  const s = silent ? null : spinner();
@@ -421,6 +442,11 @@ export async function createApp(options, { silent = false, environment, }) {
421
442
  }
422
443
  s?.stop(`Applied toolchain ${options.toolchain}...`);
423
444
  }
445
+ if (options.toolchain === 'eslint+prettier') {
446
+ s?.start(`Applying toolchain ${options.toolchain}...`);
447
+ await environment.execute(options.packageManager, ['run', 'check'], targetDir);
448
+ s?.stop(`Applied toolchain ${options.toolchain}...`);
449
+ }
424
450
  if (options.git) {
425
451
  s?.start(`Initializing git repository...`);
426
452
  await environment.execute('git', ['init'], resolve(targetDir));
package/dist/toolchain.js CHANGED
@@ -1,2 +1,6 @@
1
- export const SUPPORTED_TOOLCHAINS = ['none', 'biome'];
1
+ export const SUPPORTED_TOOLCHAINS = [
2
+ 'none',
3
+ 'biome',
4
+ 'eslint+prettier',
5
+ ];
2
6
  export const DEFAULT_TOOLCHAIN = 'none';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-tsrouter-app",
3
- "version": "0.9.7",
3
+ "version": "0.10.0",
4
4
  "description": "Tanstack Application Builder",
5
5
  "bin": "./dist/index.js",
6
6
  "type": "module",
package/src/create-app.ts CHANGED
@@ -216,6 +216,25 @@ async function createPackageJSON(
216
216
  },
217
217
  }
218
218
  }
219
+ if (options.toolchain === 'eslint+prettier') {
220
+ const eslintPrettierPackageJSON = JSON.parse(
221
+ await environment.readFile(
222
+ resolve(templateDir, 'package.eslintprettier.json'),
223
+ 'utf-8',
224
+ ),
225
+ )
226
+ packageJSON = {
227
+ ...packageJSON,
228
+ scripts: {
229
+ ...packageJSON.scripts,
230
+ ...eslintPrettierPackageJSON.scripts,
231
+ },
232
+ devDependencies: {
233
+ ...packageJSON.devDependencies,
234
+ ...eslintPrettierPackageJSON.devDependencies,
235
+ },
236
+ }
237
+ }
219
238
  if (options.mode === FILE_ROUTER) {
220
239
  const frPackageJSON = JSON.parse(
221
240
  await environment.readFile(resolve(routerDir, 'package.fr.json'), 'utf8'),
@@ -400,6 +419,18 @@ export async function createApp(
400
419
  copyFiles(templateDirBase, ['./toolchain/biome.json'], true)
401
420
  }
402
421
 
422
+ if (options.toolchain === 'eslint+prettier') {
423
+ copyFiles(
424
+ templateDirBase,
425
+ [
426
+ './toolchain/eslint.config.js',
427
+ './toolchain/prettier.config.js',
428
+ './toolchain/.prettierignore',
429
+ ],
430
+ true,
431
+ )
432
+ }
433
+
403
434
  // Setup reportWebVitals
404
435
  if (!isAddOnEnabled('start') && options.framework === 'react') {
405
436
  if (options.typescript) {
@@ -431,7 +462,7 @@ export async function createApp(
431
462
  )
432
463
  }
433
464
 
434
- // Setup the package.json file, optionally with typescript, tailwind and biome
465
+ // Setup the package.json file, optionally with typescript, tailwind and formatter/linter
435
466
  await createPackageJSON(
436
467
  environment,
437
468
  options.projectName,
@@ -696,6 +727,16 @@ export async function createApp(
696
727
  s?.stop(`Applied toolchain ${options.toolchain}...`)
697
728
  }
698
729
 
730
+ if (options.toolchain === 'eslint+prettier') {
731
+ s?.start(`Applying toolchain ${options.toolchain}...`)
732
+ await environment.execute(
733
+ options.packageManager,
734
+ ['run', 'check'],
735
+ targetDir,
736
+ )
737
+ s?.stop(`Applied toolchain ${options.toolchain}...`)
738
+ }
739
+
699
740
  if (options.git) {
700
741
  s?.start(`Initializing git repository...`)
701
742
  await environment.execute('git', ['init'], resolve(targetDir))
package/src/toolchain.ts CHANGED
@@ -1,3 +1,7 @@
1
- export const SUPPORTED_TOOLCHAINS = ['none', 'biome'] as const
1
+ export const SUPPORTED_TOOLCHAINS = [
2
+ 'none',
3
+ 'biome',
4
+ 'eslint+prettier',
5
+ ] as const
2
6
  export type ToolChain = (typeof SUPPORTED_TOOLCHAINS)[number]
3
7
  export const DEFAULT_TOOLCHAIN: ToolChain = 'none'
@@ -24,6 +24,15 @@ export const createRouter = () => {
24
24
  },
25
25
  scrollRestoration: true,
26
26
  defaultPreloadStaleTime: 0,
27
+ <% if (addOnEnabled.tRPC) { %>
28
+ Wrap: (props: { children: React.ReactNode }) => {
29
+ return (
30
+ <TanstackQuery.Provider>
31
+ {props.children}
32
+ </TanstackQuery.Provider>
33
+ );
34
+ },
35
+ <% } %>
27
36
  }), TanstackQuery.getContext().queryClient)
28
37
  <% } else { %>
29
38
  const router = createTanstackRouter({
@@ -0,0 +1,9 @@
1
+ import { initTRPC } from "@trpc/server";
2
+ import superjson from "superjson";
3
+
4
+ const t = initTRPC.create({
5
+ transformer: superjson,
6
+ });
7
+
8
+ export const createTRPCRouter = t.router;
9
+ export const publicProcedure = t.procedure;
@@ -0,0 +1,4 @@
1
+ import { createTRPCContext } from "@trpc/tanstack-react-query";
2
+ import type { TRPCRouter } from "@/trpc/router";
3
+
4
+ export const { TRPCProvider, useTRPC } = createTRPCContext<TRPCRouter>();
@@ -0,0 +1,18 @@
1
+ import { TRPCError } from '@trpc/server'
2
+ import type { TRPCRouterRecord } from '@trpc/server'
3
+ // import { z } from 'zod'
4
+
5
+ import { createTRPCRouter, publicProcedure } from './init'
6
+
7
+ const peopleRouter = {
8
+ list: publicProcedure.query(async () =>
9
+ fetch('https://swapi.dev/api/people')
10
+ .then((res) => res.json())
11
+ .then((d) => d.results as { name: string }[]),
12
+ ),
13
+ } satisfies TRPCRouterRecord
14
+
15
+ export const trpcRouter = createTRPCRouter({
16
+ people: peopleRouter,
17
+ })
18
+ export type TRPCRouter = typeof trpcRouter
@@ -0,0 +1,16 @@
1
+ import { createAPIFileRoute } from '@tanstack/react-start/api'
2
+ import { fetchRequestHandler } from '@trpc/server/adapters/fetch'
3
+ import { trpcRouter } from '@/integrations/trpc/router'
4
+
5
+ function handler({ request }: { request: Request }) {
6
+ return fetchRequestHandler({
7
+ req: request,
8
+ router: trpcRouter,
9
+ endpoint: '/api/trpc',
10
+ })
11
+ }
12
+
13
+ export const APIRoute = createAPIFileRoute('/api/trpc/$')({
14
+ GET: handler,
15
+ POST: handler,
16
+ })
@@ -0,0 +1,9 @@
1
+ {
2
+ "name": "tRPC",
3
+ "description": "Integrate tRPC into your application.",
4
+ "phase": "add-on",
5
+ "templates": ["file-router"],
6
+ "link": "https://trpc.io/",
7
+ "routes": [],
8
+ "dependsOn": ["tanstack-query", "start"]
9
+ }
@@ -0,0 +1,9 @@
1
+ {
2
+ "dependencies": {
3
+ "@trpc/client": "^11.0.0",
4
+ "@trpc/server": "^11.0.0",
5
+ "@trpc/tanstack-react-query": "^11.0.0",
6
+ "superjson": "^2.2.2",
7
+ "zod": "^3.24.2"
8
+ }
9
+ }
@@ -0,0 +1,70 @@
1
+ <% if (addOnEnabled.tRPC) { %>
2
+ import { QueryClient } from "@tanstack/react-query";
3
+ import superjson from "superjson";
4
+ import { createTRPCClient, httpBatchStreamLink } from "@trpc/client";
5
+ import { createTRPCOptionsProxy } from "@trpc/tanstack-react-query";
6
+
7
+ import { TRPCProvider } from "@/integrations/trpc/react";
8
+
9
+ import type { TRPCRouter } from "@/integrations/trpc/router";
10
+
11
+ function getUrl() {
12
+ const base = (() => {
13
+ if (typeof window !== "undefined") return "";
14
+ return `http://localhost:${process.env.PORT ?? 3000}`;
15
+ })();
16
+ return base + "/api/trpc";
17
+ }
18
+
19
+ export const trpcClient = createTRPCClient<TRPCRouter>({
20
+ links: [
21
+ httpBatchStreamLink({
22
+ transformer: superjson,
23
+ url: getUrl(),
24
+ }),
25
+ ],
26
+ });
27
+
28
+ const queryClient = new QueryClient({
29
+ defaultOptions: {
30
+ dehydrate: { serializeData: superjson.serialize },
31
+ hydrate: { deserializeData: superjson.deserialize },
32
+ },
33
+ });
34
+
35
+ const serverHelpers = createTRPCOptionsProxy({
36
+ client: trpcClient,
37
+ queryClient: queryClient,
38
+ });
39
+
40
+ export function getContext() {
41
+ return {
42
+ queryClient,
43
+ trpc: serverHelpers,
44
+ };
45
+ }
46
+
47
+ export function Provider({ children }: { children: React.ReactNode }) {
48
+ return (
49
+ <TRPCProvider trpcClient={trpcClient} queryClient={queryClient}>
50
+ {children}
51
+ </TRPCProvider>
52
+ );
53
+ }
54
+ <% } else { %>
55
+ import { QueryClient, QueryClientProvider } from '@tanstack/react-query'
56
+
57
+ const queryClient = new QueryClient()
58
+
59
+ export function getContext() {
60
+ return {
61
+ queryClient,
62
+ }
63
+ }
64
+
65
+ export function Provider({ children }: { children: React.ReactNode }) {
66
+ return (
67
+ <QueryClientProvider client={queryClient}>{children}</QueryClientProvider>
68
+ )
69
+ }
70
+ <% } %>
@@ -1,21 +1,36 @@
1
1
  import { <% if (fileRouter) { %>createFileRoute<% } else { %>createRoute<% } %> } from '@tanstack/react-router'
2
2
  import { useQuery } from '@tanstack/react-query'
3
+ <% if (addOnEnabled.tRPC) { %>
4
+ import { useTRPC } from "@/integrations/trpc/react";
5
+ <% } %>
3
6
  <% if (codeRouter) { %>
4
7
  import type { RootRoute } from '@tanstack/react-router'
5
8
  <% } else { %>
6
9
  export const Route = createFileRoute('/demo/tanstack-query')({
10
+ <% if (addOnEnabled.tRPC) { %>
11
+ loader: async ({ context }) => {
12
+ await context.queryClient.prefetchQuery(
13
+ context.trpc.people.list.queryOptions()
14
+ );
15
+ },
16
+ <% } %>
7
17
  component: TanStackQueryDemo,
8
18
  })
9
19
  <% } %>
10
20
  function TanStackQueryDemo() {
21
+ <% if (addOnEnabled.tRPC) { %>
22
+ const trpc = useTRPC();
23
+ const { data } = useQuery(trpc.people.list.queryOptions());
24
+ <% } else { %>
11
25
  const { data } = useQuery({
12
26
  queryKey: ['people'],
13
27
  queryFn: () =>
14
28
  fetch('https://swapi.dev/api/people')
15
29
  .then((res) => res.json())
16
- .then((data) => data.results as { name: string }[]),
30
+ .then((d) => d.results as { name: string }[]),
17
31
  initialData: [],
18
32
  })
33
+ <% } %>
19
34
 
20
35
  return (
21
36
  <div className="p-4">
@@ -31,17 +31,20 @@ This project uses [Tailwind CSS](https://tailwindcss.com/) for styling.
31
31
  <% } else { %>
32
32
  This project uses CSS for styling.
33
33
  <% } %>
34
- <% if (toolchain && toolchain === 'biome') { %>
34
+ <% if (toolchain && toolchain !== 'none') { %>
35
35
  ## Linting & Formatting
36
+ <% if (toolchain === 'biome') { %>
36
37
  This project uses [Biome](https://biomejs.dev/) for linting and formatting. The following scripts are available:
37
-
38
+ <% } %>
39
+ <% if (toolchain === 'eslint+prettier') { %>
40
+ This project uses [eslint](https://eslint.org/) and [prettier](https://prettier.io/) for linting and formatting. Eslint is configured using [tanstack/eslint-config](https://tanstack.com/config/latest/docs/eslint). The following scripts are available:
41
+ <% } %>
38
42
  ```bash
39
43
  <%= getPackageManagerRunScript('lint') %>
40
44
  <%= getPackageManagerRunScript('format') %>
41
45
  <%= getPackageManagerRunScript('check') %>
42
46
  ```
43
47
  <% } %>
44
-
45
48
  <% for(const addon of addOns.filter(addon => addon.readme)) { %>
46
49
  <%- addon.readme %>
47
50
  <% } %>
@@ -0,0 +1,11 @@
1
+ {
2
+ "scripts": {
3
+ "lint": "eslint",
4
+ "format": "prettier",
5
+ "check": "prettier --write . && eslint --fix"
6
+ },
7
+ "devDependencies": {
8
+ "@tanstack/eslint-config": "^0.1.0",
9
+ "prettier": "^3.5.3"
10
+ }
11
+ }
@@ -0,0 +1,3 @@
1
+ package-lock.json
2
+ pnpm-lock.yaml
3
+ yarn.lock
@@ -0,0 +1,5 @@
1
+ // @ts-check
2
+
3
+ import { tanstackConfig } from "@tanstack/eslint-config";
4
+
5
+ export default [...tanstackConfig];
@@ -0,0 +1,10 @@
1
+ // @ts-check
2
+
3
+ /** @type {import('prettier').Config} */
4
+ const config = {
5
+ semi: false,
6
+ singleQuote: true,
7
+ trailingComma: "all",
8
+ };
9
+
10
+ export default config;
@@ -1,5 +1,6 @@
1
1
  {
2
- "include": ["**/*.ts", "**/*.tsx"],
2
+ <% if (toolchain && toolchain === 'eslint+prettier') { %>"include": ["**/*.ts", "**/*.tsx", "eslint.config.js", "prettier.config.js", "vite.config.js"],
3
+ <% } else { %>"include": ["**/*.ts", "**/*.tsx"],<% } %>
3
4
  "compilerOptions": {
4
5
  "target": "ES2022",
5
6
  "jsx": "react-jsx",
@@ -19,10 +20,10 @@
19
20
  "noUnusedLocals": true,
20
21
  "noUnusedParameters": true,
21
22
  "noFallthroughCasesInSwitch": true,
22
- "noUncheckedSideEffectImports": true<% if (addOnEnabled.shadcn) { %>,
23
+ "noUncheckedSideEffectImports": true,
23
24
  "baseUrl": ".",
24
25
  "paths": {
25
26
  "@/*": ["./src/*"],
26
- }<% } %>
27
+ }
27
28
  }
28
29
  }
@@ -3,8 +3,8 @@ 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) { %>
7
- import { resolve } from "node:path";<% } %><% if (addOnEnabled['module-federation']) { %>
6
+ import { federation } from "@module-federation/vite";<% } %>
7
+ import { resolve } from "node:path";<% if (addOnEnabled['module-federation']) { %>
8
8
  import federationConfig from "./module-federation.config.js";
9
9
  <% } %>
10
10
 
@@ -15,10 +15,9 @@ export default defineConfig({
15
15
  globals: true,
16
16
  environment: "jsdom",
17
17
  },
18
- <% if (addOnEnabled.shadcn) { %> resolve: {
18
+ resolve: {
19
19
  alias: {
20
20
  '@': resolve(__dirname, './src'),
21
21
  },
22
- },
23
- <% } %>
22
+ }
24
23
  });
@@ -10,16 +10,26 @@ export interface Guitar {
10
10
  const guitars: Array<Guitar> = [
11
11
  {
12
12
  id: 1,
13
- name: 'Dune Guitar',
14
- image: '/example-guitar-dune.jpg',
13
+ name: 'Video Game Guitar',
14
+ image: '/example-guitar-video-games.jpg',
15
15
  description:
16
- 'Inspired by the desert, this guitar will transport you to a world of sand and adventure. Its warm, amber-toned finish mimics the endless dunes of Arrakis, while the custom fretboard inlays resemble ancient desert glyphs. The resonant hollow body produces tones that range from whispered sandstorm hushes to the booming echo of desert thunder. Perfect for musicians seeking an instrument with both visual impact and sonic versatility, the Dune Guitar carries the mystique of distant worlds in every note.',
16
+ "The Video Game Guitar is a unique acoustic guitar that features a design inspired by video games. It has a sleek, high-gloss finish and a comfortable playability. The guitar's ergonomic body and fast neck profile ensure comfortable playability for hours on end.",
17
17
  shortDescription:
18
- 'A desert-inspired hollow body guitar with warm tones and custom desert glyph inlays.',
19
- price: 599,
18
+ 'A unique electric guitar with a video game design, high-gloss finish, and comfortable playability.',
19
+ price: 699,
20
20
  },
21
21
  {
22
22
  id: 2,
23
+ name: 'Superhero Guitar',
24
+ image: '/example-guitar-superhero.jpg',
25
+ description:
26
+ "The Superhero Guitar is a bold black electric guitar that stands out with its unique superhero logo design. Its sleek, high-gloss finish and powerful pickups make it perfect for high-energy performances. The guitar's ergonomic body and fast neck profile ensure comfortable playability for hours on end.",
27
+ shortDescription:
28
+ 'A bold black electric guitar with a unique superhero logo, high-gloss finish, and powerful pickups.',
29
+ price: 699,
30
+ },
31
+ {
32
+ id: 3,
23
33
  name: 'Motherboard Guitar',
24
34
  image: '/example-guitar-motherboard.jpg',
25
35
  description:
@@ -29,7 +39,7 @@ const guitars: Array<Guitar> = [
29
39
  price: 649,
30
40
  },
31
41
  {
32
- id: 3,
42
+ id: 4,
33
43
  name: 'Racing Guitar',
34
44
  image: '/example-guitar-racing.jpg',
35
45
  description:
@@ -39,34 +49,34 @@ const guitars: Array<Guitar> = [
39
49
  price: 679,
40
50
  },
41
51
  {
42
- id: 4,
52
+ id: 5,
43
53
  name: 'Steamer Trunk Guitar',
44
54
  image: '/example-guitar-steamer-trunk.jpg',
45
55
  description:
46
- "The Steamer Trunk Guitar carries the nostalgic essence of vintage travel in its unique design. Crafted with reclaimed wood from authentic antique luggage, each instrument tells a story of journeys past through its weathered finish and brass hardware accents. The body features decorative leather straps and corner protectors reminiscent of classic travel trunks, while the neck is inlaid with miniature world map markers denoting famous destinations. Its warm, rich tone has a distinctive aged quality that can't be replicated, producing sounds that evoke distant shores and adventures waiting to be had. Perfect for the musician whose playing is a journey unto itself.",
56
+ 'The Steamer Trunk Guitar is a semi-hollow body instrument that exudes vintage charm and character. Crafted from reclaimed antique luggage wood, it features brass hardware that adds a touch of elegance and durability. The fretboard is adorned with a world map inlay, making it a unique piece that tells a story of travel and adventure.',
47
57
  shortDescription:
48
- 'A nostalgic guitar crafted from reclaimed antique luggage wood with brass accents and world map inlays.',
58
+ 'A semi-hollow body guitar with brass hardware and a world map inlay, crafted from reclaimed antique luggage wood.',
49
59
  price: 629,
50
60
  },
51
61
  {
52
- id: 5,
53
- name: 'Steampunk Guitar',
54
- image: '/example-guitar-steampunk.jpg',
62
+ id: 6,
63
+ name: "Travelin' Man Guitar",
64
+ image: '/example-guitar-traveling.jpg',
55
65
  description:
56
- "The Steampunk Guitar is a magnificent fusion of Victorian aesthetics and industrial innovation, featuring an array of functional brass gears, pressure gauges, and copper tubing that adorn its mahogany body. Each component has been meticulously hand-crafted by master artisans, creating not just an instrument but a work of mechanical art. The fretboard is inlaid with vintage clockwork designs that seem to move as you play, while the custom-wound pickups are housed in polished brass casings that enhance the guitar's warm, slightly overdriven tone. Steam-powered tremolo effects can be activated via the special valve system, producing otherworldly sounds that transport listeners to an alternate history where steam and music power the world.",
66
+ "The Travelin' Man Guitar is an acoustic masterpiece adorned with vintage postcards from around the world. Each postcard tells a story of adventure and wanderlust, making this guitar a unique piece of art. Its rich, resonant tones and comfortable playability make it perfect for musicians who love to travel and perform.",
57
67
  shortDescription:
58
- 'A Victorian-inspired masterpiece featuring functional brass gears, pressure gauges, and copper tubing on a mahogany body.',
59
- price: 699,
68
+ 'An acoustic guitar with vintage postcards, rich tones, and comfortable playability.',
69
+ price: 499,
60
70
  },
61
71
  {
62
- id: 6,
63
- name: 'Underwater Guitar',
64
- image: '/example-guitar-underwater.jpg',
72
+ id: 7,
73
+ name: 'Flowerly Love Guitar',
74
+ image: '/example-guitar-flowers.jpg',
65
75
  description:
66
- 'Dive into the depths of sonic exploration with the Underwater Guitar, an instrument designed to capture the mysterious beauty of the ocean. Its translucent blue-green finish creates the illusion of being submerged, with mother-of-pearl inlays resembling bubbles rising along the fretboard. The body is contoured like ocean waves, featuring hand-painted coral reef details and iridescent abalone accents that shimmer like sunlight through water. Specially designed pickups produce ethereal, fluid tones with extended sustain that mimics the endless nature of the sea. Water-resistant components make this guitar surprisingly practical for beachside performances, while its unique resonant chamber creates haunting harmonics reminiscent of whale songs and the gentle lapping of waves.',
76
+ "The Flowerly Love Guitar is an acoustic masterpiece adorned with intricate floral designs on its body. Each flower is hand-painted, adding a touch of nature's beauty to the instrument. Its warm, resonant tones make it perfect for both intimate performances and larger gatherings.",
67
77
  shortDescription:
68
- 'An ocean-themed guitar with a translucent blue-green finish, bubble-like pearl inlays, and ethereal tones with extended sustain.',
69
- price: 499,
78
+ 'An acoustic guitar with hand-painted floral designs and warm, resonant tones.',
79
+ price: 599,
70
80
  },
71
81
  ]
72
82
 
@@ -2,10 +2,10 @@ import { Link, createFileRoute } from '@tanstack/react-router'
2
2
  import guitars from '../../data/example-guitars'
3
3
 
4
4
  export const Route = createFileRoute('/example/guitars/')({
5
- component: App,
5
+ component: GuitarsIndex,
6
6
  })
7
7
 
8
- export default function App() {
8
+ function GuitarsIndex() {
9
9
  return (
10
10
  <div className="bg-black text-white p-5">
11
11
  <h1 className="text-3xl font-bold mb-8 text-center">Featured Guitars</h1>
@@ -10,8 +10,15 @@ import <%= integration.name %> from "../<%= integration.path %>";
10
10
  import appCss from '../styles.css?url'
11
11
  <% } %><% if (addOnEnabled["tanstack-query"]) { %>
12
12
  import type { QueryClient } from '@tanstack/react-query'
13
+ <% if (addOnEnabled.tRPC) { %>
14
+ import { TRPCRouter } from '@/integrations/trpc/router'
15
+ <% } %>
16
+
13
17
  interface MyRouterContext {
14
18
  queryClient: QueryClient
19
+ <% if (addOnEnabled.tRPC) { %>
20
+ trpc: TRPCRouter
21
+ <% } %>
15
22
  }<% } %>
16
23
 
17
24
  export const Route = <% if (addOnEnabled["tanstack-query"]) { %>createRootRouteWithContext<MyRouterContext>()<% } else { %>createRootRoute<% } %>({
@@ -195,6 +195,21 @@ Loaders simplify your data fetching logic dramatically. Check out more informati
195
195
 
196
196
  Files prefixed with `demo` can be safely deleted. They are there to provide a starting point for you to play around with the features you've installed.
197
197
 
198
+ <% if (toolchain && toolchain !== 'none') { %>
199
+ ## Linting & Formatting
200
+ <% if (toolchain === 'biome') { %>
201
+ This project uses [Biome](https://biomejs.dev/) for linting and formatting. The following scripts are available:
202
+ <% } %>
203
+ <% if (toolchain === 'eslint+prettier') { %>
204
+ This project uses [eslint](https://eslint.org/) and [prettier](https://prettier.io/) for linting and formatting. Eslint is configured using [tanstack/eslint-config](https://tanstack.com/config/latest/docs/eslint). The following scripts are available:
205
+ <% } %>
206
+ ```bash
207
+ <%= getPackageManagerRunScript('lint') %>
208
+ <%= getPackageManagerRunScript('format') %>
209
+ <%= getPackageManagerRunScript('check') %>
210
+ ```
211
+ <% } %>
212
+
198
213
  # Learn More
199
214
 
200
215
  You can learn more about all of the offerings from TanStack in the [TanStack documentation](https://tanstack.com).