Skip to content

Commit 50633ca

Browse files
committed
update 01-routing
1 parent d9c67ca commit 50633ca

20 files changed

Lines changed: 521 additions & 20 deletions

File tree

04-frameworks/17-tanstack-start/00-boilerplate/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,5 @@ junit.xml
1010
.env
1111
.next
1212
.swc
13+
!.vscode
14+
.tanstack
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"files.watcherExclude": {
3+
"**/routeTree.gen.ts": true
4+
},
5+
"search.exclude": {
6+
"**/routeTree.gen.ts": true
7+
},
8+
"files.readonlyInclude": {
9+
"**/routeTree.gen.ts": true
10+
}
11+
}

04-frameworks/17-tanstack-start/00-boilerplate/index.tsx

Lines changed: 0 additions & 8 deletions
This file was deleted.

04-frameworks/17-tanstack-start/00-boilerplate/tsconfig.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
"allowJs": true,
1212
"skipLibCheck": true,
1313
"esModuleInterop": true,
14+
"strictNullChecks": true,
1415
"baseUrl": "./src/",
1516
"paths": {
1617
"#*": ["*"]

04-frameworks/17-tanstack-start/00-boilerplate/vite-env.d.ts

Lines changed: 0 additions & 1 deletion
This file was deleted.

04-frameworks/17-tanstack-start/01-routing/.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,3 +10,5 @@ junit.xml
1010
.env
1111
.next
1212
.swc
13+
!.vscode
14+
.tanstack
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"files.watcherExclude": {
3+
"**/routeTree.gen.ts": true
4+
},
5+
"search.exclude": {
6+
"**/routeTree.gen.ts": true
7+
},
8+
"files.readonlyInclude": {
9+
"**/routeTree.gen.ts": true
10+
}
11+
}
Lines changed: 273 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,273 @@
1+
# 01 Routing
2+
3+
In this example we are going to add a basic routing setup using TanStack Router.
4+
5+
We will start from `00-boilerplate`.
6+
7+
# Steps to build it
8+
9+
`npm install` to install previous sample packages:
10+
11+
```bash
12+
npm install
13+
```
14+
15+
Install necessary libraries.
16+
17+
```bash
18+
npm install @tanstack/react-router --save
19+
20+
npm install @tanstack/router-plugin @tanstack/react-router-devtools --save-dev
21+
```
22+
23+
> [More info about TanStack Router Quick Start](https://tanstack.com/router/latest/docs/framework/react/quick-start)
24+
>
25+
> [Manual setup](https://tanstack.com/router/latest/docs/framework/react/installation/manual)
26+
27+
Configure the router plugin:
28+
29+
_./vite.config.ts_
30+
31+
```diff
32+
+ import { tanstackRouter } from '@tanstack/router-plugin/vite';
33+
import react from '@vitejs/plugin-react';
34+
import { defineConfig } from 'vite';
35+
36+
export default defineConfig({
37+
plugins: [
38+
+ tanstackRouter({
39+
+ target: 'react',
40+
+ autoCodeSplitting: true,
41+
+ }),
42+
react(),
43+
],
44+
css: {
45+
modules: {
46+
localsConvention: 'camelCase',
47+
},
48+
},
49+
});
50+
51+
```
52+
53+
> target: 'react' or 'solid' depending on the framework used.
54+
>
55+
> autoCodeSplitting: true to enable automatic code splitting based on routes.
56+
57+
Let's start the application:
58+
59+
```bash
60+
npm start
61+
```
62+
63+
And we should see some warning in the console about missing router configuration. Let's create it.
64+
65+
- Create a file in the route: `./src/routes/__root.tsx`. Automatically the router plugin will write the necessary code to configure the router.
66+
67+
We can update it with the `dev tools` configuration:
68+
69+
_./src/routes/\_\_root.tsx_
70+
71+
```diff
72+
import { Outlet, createRootRoute } from '@tanstack/react-router'
73+
+ import { TanStackRouterDevtools } from '@tanstack/react-router-devtools';
74+
import * as React from 'react'
75+
76+
export const Route = createRootRoute({
77+
component: RootComponent,
78+
})
79+
80+
function RootComponent() {
81+
return (
82+
<React.Fragment>
83+
<div>Hello "__root"!</div>
84+
<Outlet />
85+
+ <TanStackRouterDevtools />
86+
</React.Fragment>
87+
)
88+
}
89+
90+
```
91+
92+
> the `Outlet` component is necessary to render child routes.
93+
94+
Notice that the router plugin also created the `./src/routeTree.gen.ts` file that contains all the route types that we are going to create.
95+
96+
> We also have a `.vscode/settings.json` file that configures this file as read-only to avoid accidental changes and it is excluded from typescript watching.
97+
98+
Let's use this router in the main application file:
99+
100+
_./src/index.tsx_
101+
102+
```diff
103+
import React from 'react';
104+
import { createRoot } from 'react-dom/client';
105+
+ import { RouterProvider, createRouter } from '@tanstack/react-router';
106+
107+
+ import { routeTree } from './routeTree.gen';
108+
+ const router = createRouter({
109+
+ routeTree,
110+
+ });
111+
+ // Register the router instance for type safety
112+
+ declare module '@tanstack/react-router' {
113+
+ interface Register {
114+
+ router: typeof router;
115+
+ }
116+
+ }
117+
118+
createRoot(document.getElementById('root')!).render(
119+
<React.StrictMode>
120+
- <h1>Welcome to Rent a Car!</h1>
121+
+ <RouterProvider router={router} />
122+
</React.StrictMode>
123+
);
124+
125+
```
126+
127+
Now we can create two route:
128+
129+
- The main route `src/routes/index.tsx`
130+
- A second route `src/routes/cars.tsx`
131+
132+
And we have intellisense and type safety when navigating between them:
133+
134+
_./src/routes/index.tsx_
135+
136+
```diff
137+
- import { createFileRoute } from '@tanstack/react-router'
138+
+ import { createFileRoute, Link } from '@tanstack/react-router';
139+
140+
export const Route = createFileRoute('/')({
141+
component: RouteComponent,
142+
})
143+
144+
function RouteComponent() {
145+
- return <div>Hello "/"!</div>
146+
+ return (
147+
+ <>
148+
+ <div>Hello "/"!</div>
149+
+ <Link to="/cars">Navigate to car list</Link>
150+
+ </>
151+
+ );
152+
}
153+
154+
```
155+
156+
Also if we use the [useNavigate](https://tanstack.com/router/v1/docs/framework/react/api/router/useNavigateHook) hook we have type safety when navigating programmatically:
157+
158+
_./src/routes/cars.tsx_
159+
160+
```diff
161+
- import { createFileRoute } from '@tanstack/react-router'
162+
+ import { createFileRoute, useNavigate } from '@tanstack/react-router';
163+
164+
export const Route = createFileRoute('/cars')({
165+
component: RouteComponent,
166+
})
167+
168+
function RouteComponent() {
169+
- return <div>Hello "/cars"!</div>
170+
+ const navigate = useNavigate();
171+
172+
+ return (
173+
+ <>
174+
+ <div>Hello "/cars"!</div>
175+
+ <button onClick={() => navigate({ to: '/' })}>Go back to home</button>
176+
+ </>
177+
+ );
178+
}
179+
180+
```
181+
182+
If we need dynamic routes, we can create them using the `$param` syntax. Let's create the `cars` folder and move the previous `cars.tsx` file into it as `index.tsx`. Then create a new file `$id.tsx` for the dynamic route:
183+
184+
```
185+
|routes/
186+
|-- cars/
187+
|----- $id.tsx ----------------> Route with param `/cars/:id`
188+
|----- index.tsx --------------> Main route `/cars`
189+
|----- route.tsx --------------> Shared route config for `/cars` routes
190+
|-- __root.tsx
191+
|-- index.tsx
192+
```
193+
194+
_./src/routes/cars/$id.tsx_
195+
196+
```diff
197+
import { createFileRoute } from '@tanstack/react-router';
198+
199+
export const Route = createFileRoute('/cars/$id')({
200+
component: RouteComponent,
201+
});
202+
203+
function RouteComponent() {
204+
+ const { id } = Route.useParams();
205+
- return <div>Hello "/cars/$id"!</div>
206+
+ return <div>Car id={id}</div>;
207+
}
208+
209+
```
210+
211+
> `import { useParams } from '@tanstack/react-router'` and `const { id } = useParams({from: '/cars/$id'})` if we don't have access to the Route object.
212+
213+
_./src/routes/cars/index.tsx_
214+
215+
```diff
216+
- import { createFileRoute, useNavigate } from '@tanstack/react-router';
217+
+ import { createFileRoute, useNavigate, Link } from '@tanstack/react-router';
218+
219+
export const Route = createFileRoute('/cars/')({
220+
component: RouteComponent,
221+
});
222+
223+
function RouteComponent() {
224+
const navigate = useNavigate();
225+
226+
return (
227+
<>
228+
<div>Hello "/cars"!</div>
229+
+ <Link to="/cars/$id" params={{ id: '1' }}>
230+
+ Navigate to car 1
231+
+ </Link>
232+
<button onClick={() => navigate({ to: '/' })}>Go back to home</button>
233+
</>
234+
);
235+
}
236+
237+
```
238+
239+
> Also check the params typing when using the `navigate` function.
240+
241+
Finally we can create a shared route config for all the `cars` routes:
242+
243+
_./src/routes/cars/route.tsx_
244+
245+
```diff
246+
- import { createFileRoute } from '@tanstack/react-router'
247+
+ import { createFileRoute, Outlet } from '@tanstack/react-router';
248+
249+
export const Route = createFileRoute('/cars')({
250+
component: RouteComponent,
251+
})
252+
253+
function RouteComponent() {
254+
- return <div>Hello "/cars"!</div>
255+
+ return (
256+
+ <>
257+
+ <div style={{ background: 'teal' }}>Common layout</div>
258+
+ <Outlet />
259+
+ </>
260+
+ );
261+
}
262+
263+
```
264+
265+
# About Basefactor + Lemoncode
266+
267+
We are an innovating team of Javascript experts, passionate about turning your ideas into robust products.
268+
269+
[Basefactor, consultancy by Lemoncode](http://www.basefactor.com) provides consultancy and coaching services.
270+
271+
[Lemoncode](http://lemoncode.net/services/en/#en-home) provides training services.
272+
273+
For the LATAM/Spanish audience we are running an Online Front End Master degree, more info: http://lemoncode.net/master-frontend

04-frameworks/17-tanstack-start/01-routing/index.tsx

Lines changed: 0 additions & 8 deletions
This file was deleted.

04-frameworks/17-tanstack-start/01-routing/package.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,13 @@
1515
"author": "Lemoncode",
1616
"license": "MIT",
1717
"dependencies": {
18+
"@tanstack/react-router": "^1.141.2",
1819
"react": "^19.2.3",
1920
"react-dom": "^19.2.3"
2021
},
2122
"devDependencies": {
23+
"@tanstack/react-router-devtools": "^1.141.2",
24+
"@tanstack/router-plugin": "^1.141.2",
2225
"@types/react": "^19.2.7",
2326
"@types/react-dom": "^19.2.3",
2427
"@vitejs/plugin-react": "^5.1.2",

0 commit comments

Comments
 (0)