@tanstack/react-router 1.132.47 → 1.133.3
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.
- package/dist/llms/rules/guide.d.ts +1 -1
- package/dist/llms/rules/guide.js +9 -4
- package/dist/llms/rules/routing.d.ts +1 -1
- package/dist/llms/rules/routing.js +5 -444
- package/dist/llms/rules/setup-and-architecture.d.ts +1 -1
- package/dist/llms/rules/setup-and-architecture.js +835 -218
- package/package.json +22 -4
|
@@ -161,247 +161,139 @@ Enough overview, there's so much more to do with TanStack Router. Hit that next
|
|
|
161
161
|
|
|
162
162
|
# Quick Start
|
|
163
163
|
|
|
164
|
-
|
|
164
|
+
TanStack Router can be quickly added to any existing React project or used to scaffold a new one.
|
|
165
165
|
|
|
166
|
-
##
|
|
166
|
+
## TanStack Router Installation
|
|
167
167
|
|
|
168
|
-
|
|
168
|
+
### Requirements
|
|
169
169
|
|
|
170
|
-
|
|
170
|
+
Before installing TanStack router, please ensure your project meets the following requirements:
|
|
171
171
|
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
172
|
+
[//]: # 'Requirements'
|
|
173
|
+
|
|
174
|
+
- \`react\` v18 or later with \`createRoot\` support.
|
|
175
|
+
- \`react-dom\` v18 or later.
|
|
175
176
|
|
|
176
|
-
|
|
177
|
+
[//]: # 'Requirements'
|
|
177
178
|
|
|
178
|
-
|
|
179
|
+
> [!NOTE] Using TypeScript (\`v5.3.x or higher\`) is recommended for the best development experience, though not strictly required. We aim to support the last 5 minor versions of TypeScript, but using the latest version will help avoid potential issues.
|
|
179
180
|
|
|
180
|
-
|
|
181
|
+
TanStack Router is currently only compatible with React (with ReactDOM) and Solid. If you're interested in contributing to support other frameworks, such as React Native, Angular, or Vue, please reach out to us on [Discord](https://tlinz.com/discord).
|
|
181
182
|
|
|
182
|
-
|
|
183
|
+
### Download and Install
|
|
184
|
+
|
|
185
|
+
To install TanStack Router in your project, run the following command using your preferred package manager:
|
|
186
|
+
|
|
187
|
+
[//]: # 'installCommand'
|
|
183
188
|
|
|
184
189
|
\`\`\`sh
|
|
185
|
-
npm install @tanstack/
|
|
186
|
-
npm install -D @tanstack/router-plugin
|
|
187
|
-
# or
|
|
188
|
-
pnpm add @tanstack/react-router @tanstack/react-router-devtools
|
|
189
|
-
pnpm add -D @tanstack/router-plugin
|
|
190
|
+
npm install @tanstack/router
|
|
190
191
|
# or
|
|
191
|
-
|
|
192
|
-
|
|
192
|
+
pnpm add @tanstack/router
|
|
193
|
+
#or
|
|
194
|
+
yarn add @tanstack/router
|
|
193
195
|
# or
|
|
194
|
-
bun add @tanstack/
|
|
195
|
-
bun add -D @tanstack/router-plugin
|
|
196
|
+
bun add @tanstack/router
|
|
196
197
|
# or
|
|
197
|
-
deno add npm:@tanstack/
|
|
198
|
+
deno add npm:@tanstack/router
|
|
198
199
|
\`\`\`
|
|
199
200
|
|
|
200
|
-
|
|
201
|
+
[//]: # 'installCommand'
|
|
201
202
|
|
|
202
|
-
|
|
203
|
-
// vite.config.ts
|
|
204
|
-
import { defineConfig } from 'vite'
|
|
205
|
-
import react from '@vitejs/plugin-react'
|
|
206
|
-
import { tanstackRouter } from '@tanstack/router-plugin/vite'
|
|
203
|
+
Once installed, you can verify the installation by checking your \`package.json\` file for the \`@tanstack/router\` dependency.
|
|
207
204
|
|
|
208
|
-
//
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
react(),
|
|
217
|
-
// ...,
|
|
218
|
-
],
|
|
219
|
-
})
|
|
205
|
+
[//]: # 'packageJson'
|
|
206
|
+
|
|
207
|
+
\`\`\`json
|
|
208
|
+
{
|
|
209
|
+
"dependencies": {
|
|
210
|
+
"@tanstack/react-router": "^x.x.x"
|
|
211
|
+
}
|
|
212
|
+
}
|
|
220
213
|
\`\`\`
|
|
221
214
|
|
|
222
|
-
|
|
223
|
-
> If you are not using Vite, or any of the supported bundlers, you can check out the [TanStack Router CLI](../routing/installation-with-router-cli.md) guide for more info.
|
|
215
|
+
[//]: # 'packageJson'
|
|
224
216
|
|
|
225
|
-
|
|
217
|
+
## New Project Setup
|
|
226
218
|
|
|
227
|
-
|
|
228
|
-
- \`src/routes/index.tsx\`
|
|
229
|
-
- \`src/routes/about.tsx\`
|
|
230
|
-
- \`src/main.tsx\`
|
|
219
|
+
To quickly scaffold a new project with TanStack Router, you can use the \`create-tsrouter-app\` command-line tool. This tool sets up a new React application with TanStack Router pre-configured, allowing you to get started quickly.
|
|
231
220
|
|
|
232
|
-
|
|
221
|
+
> [!TIP] For full details on available options and templates, visit the [\`create-tsrouter-app\` documentation](https://github.com/TanStack/create-tsrouter-app/tree/main/cli/create-tsrouter-app).
|
|
233
222
|
|
|
234
|
-
|
|
235
|
-
import { createRootRoute, Link, Outlet } from '@tanstack/react-router'
|
|
236
|
-
import { TanStackRouterDevtools } from '@tanstack/react-router-devtools'
|
|
223
|
+
To create a new project, run the following command in your terminal:
|
|
237
224
|
|
|
238
|
-
|
|
239
|
-
<>
|
|
240
|
-
<div className="p-2 flex gap-2">
|
|
241
|
-
<Link to="/" className="[&.active]:font-bold">
|
|
242
|
-
Home
|
|
243
|
-
</Link>{' '}
|
|
244
|
-
<Link to="/about" className="[&.active]:font-bold">
|
|
245
|
-
About
|
|
246
|
-
</Link>
|
|
247
|
-
</div>
|
|
248
|
-
<hr />
|
|
249
|
-
<Outlet />
|
|
250
|
-
<TanStackRouterDevtools />
|
|
251
|
-
</>
|
|
252
|
-
)
|
|
225
|
+
[//]: # 'createAppCommand'
|
|
253
226
|
|
|
254
|
-
|
|
227
|
+
\`\`\`sh
|
|
228
|
+
npx create-tsrouter-app@latest
|
|
255
229
|
\`\`\`
|
|
256
230
|
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
\`\`\`tsx
|
|
260
|
-
import { createFileRoute } from '@tanstack/react-router'
|
|
231
|
+
[//]: # 'createAppCommand'
|
|
261
232
|
|
|
262
|
-
|
|
263
|
-
component: Index,
|
|
264
|
-
})
|
|
233
|
+
The CLI will guide you through a short series of prompts to customize your setup, including options for:
|
|
265
234
|
|
|
266
|
-
|
|
267
|
-
return (
|
|
268
|
-
<div className="p-2">
|
|
269
|
-
<h3>Welcome Home!</h3>
|
|
270
|
-
</div>
|
|
271
|
-
)
|
|
272
|
-
}
|
|
273
|
-
\`\`\`
|
|
235
|
+
[//]: # 'CLIPrompts'
|
|
274
236
|
|
|
275
|
-
|
|
237
|
+
- File-based or code-based route configuration
|
|
238
|
+
- TypeScript support
|
|
239
|
+
- Tailwind CSS integration
|
|
240
|
+
- Toolchain setup
|
|
241
|
+
- Git initialization
|
|
276
242
|
|
|
277
|
-
|
|
278
|
-
import { createFileRoute } from '@tanstack/react-router'
|
|
243
|
+
[//]: # 'CLIPrompts'
|
|
279
244
|
|
|
280
|
-
|
|
281
|
-
component: About,
|
|
282
|
-
})
|
|
245
|
+
Once complete, a new React project will be generated with TanStack Router installed and ready to use. All dependencies are automatically installed, so you can jump straight into development:
|
|
283
246
|
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
247
|
+
\`\`\`sh
|
|
248
|
+
cd your-project-name
|
|
249
|
+
npm run dev
|
|
287
250
|
\`\`\`
|
|
288
251
|
|
|
289
|
-
|
|
252
|
+
### Routing Options
|
|
290
253
|
|
|
291
|
-
|
|
254
|
+
TanStack Router supports both file-based and code-based route configurations, allowing you to choose the approach that best fits your workflow.
|
|
292
255
|
|
|
293
|
-
|
|
256
|
+
#### File-Based Route Generation
|
|
294
257
|
|
|
295
|
-
|
|
296
|
-
import { StrictMode } from 'react'
|
|
297
|
-
import ReactDOM from 'react-dom/client'
|
|
298
|
-
import { RouterProvider, createRouter } from '@tanstack/react-router'
|
|
258
|
+
The file-based approach is the recommended option for most projects. It automatically creates routes based on your file structure, giving you the best mix of performance, simplicity, and developer experience.
|
|
299
259
|
|
|
300
|
-
|
|
301
|
-
import { routeTree } from './routeTree.gen'
|
|
260
|
+
To create a new project using file-based route generation, run the following command:
|
|
302
261
|
|
|
303
|
-
//
|
|
304
|
-
const router = createRouter({ routeTree })
|
|
305
|
-
|
|
306
|
-
// Register the router instance for type safety
|
|
307
|
-
declare module '@tanstack/react-router' {
|
|
308
|
-
interface Register {
|
|
309
|
-
router: typeof router
|
|
310
|
-
}
|
|
311
|
-
}
|
|
262
|
+
[//]: # 'createAppCommandFileBased'
|
|
312
263
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
if (!rootElement.innerHTML) {
|
|
316
|
-
const root = ReactDOM.createRoot(rootElement)
|
|
317
|
-
root.render(
|
|
318
|
-
<StrictMode>
|
|
319
|
-
<RouterProvider router={router} />
|
|
320
|
-
</StrictMode>,
|
|
321
|
-
)
|
|
322
|
-
}
|
|
264
|
+
\`\`\`sh
|
|
265
|
+
npx create-tsrouter-app@latest my-app --template file-router
|
|
323
266
|
\`\`\`
|
|
324
267
|
|
|
325
|
-
|
|
268
|
+
[//]: # 'createAppCommandFileBased'
|
|
326
269
|
|
|
327
|
-
|
|
270
|
+
This command sets up a new directory called \`my-app\` with everything configured. Once setup completes, you can then start your development server and begin building your application:
|
|
328
271
|
|
|
329
|
-
|
|
330
|
-
|
|
272
|
+
\`\`\`sh
|
|
273
|
+
cd my-app
|
|
274
|
+
npm run dev
|
|
275
|
+
\`\`\`
|
|
331
276
|
|
|
332
|
-
|
|
333
|
-
import { StrictMode } from 'react'
|
|
334
|
-
import ReactDOM from 'react-dom/client'
|
|
335
|
-
import {
|
|
336
|
-
Outlet,
|
|
337
|
-
RouterProvider,
|
|
338
|
-
Link,
|
|
339
|
-
createRouter,
|
|
340
|
-
createRoute,
|
|
341
|
-
createRootRoute,
|
|
342
|
-
} from '@tanstack/react-router'
|
|
343
|
-
import { TanStackRouterDevtools } from '@tanstack/react-router-devtools'
|
|
277
|
+
#### Code-Based Route Configuration
|
|
344
278
|
|
|
345
|
-
|
|
346
|
-
component: () => (
|
|
347
|
-
<>
|
|
348
|
-
<div className="p-2 flex gap-2">
|
|
349
|
-
<Link to="/" className="[&.active]:font-bold">
|
|
350
|
-
Home
|
|
351
|
-
</Link>{' '}
|
|
352
|
-
<Link to="/about" className="[&.active]:font-bold">
|
|
353
|
-
About
|
|
354
|
-
</Link>
|
|
355
|
-
</div>
|
|
356
|
-
<hr />
|
|
357
|
-
<Outlet />
|
|
358
|
-
<TanStackRouterDevtools />
|
|
359
|
-
</>
|
|
360
|
-
),
|
|
361
|
-
})
|
|
279
|
+
If you prefer to define routes programmatically, you can use the code-based route configuration. This approach gives you full control over routing logic while maintaining the same project scaffolding workflow.
|
|
362
280
|
|
|
363
|
-
|
|
364
|
-
getParentRoute: () => rootRoute,
|
|
365
|
-
path: '/',
|
|
366
|
-
component: function Index() {
|
|
367
|
-
return (
|
|
368
|
-
<div className="p-2">
|
|
369
|
-
<h3>Welcome Home!</h3>
|
|
370
|
-
</div>
|
|
371
|
-
)
|
|
372
|
-
},
|
|
373
|
-
})
|
|
281
|
+
[//]: # 'createAppCommandCodeBased'
|
|
374
282
|
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
component: function About() {
|
|
379
|
-
return <div className="p-2">Hello from About!</div>
|
|
380
|
-
},
|
|
381
|
-
})
|
|
283
|
+
\`\`\`sh
|
|
284
|
+
npx create-tsrouter-app@latest my-app
|
|
285
|
+
\`\`\`
|
|
382
286
|
|
|
383
|
-
|
|
287
|
+
[//]: # 'createAppCommandCodeBased'
|
|
384
288
|
|
|
385
|
-
|
|
289
|
+
Similar to the file-based setup, this command creates a new directory called \`my-app\` with TanStack Router configured for code-based routing. After setup, navigate to your project directory and start the development server:
|
|
386
290
|
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
|
|
393
|
-
const rootElement = document.getElementById('app')!
|
|
394
|
-
if (!rootElement.innerHTML) {
|
|
395
|
-
const root = ReactDOM.createRoot(rootElement)
|
|
396
|
-
root.render(
|
|
397
|
-
<StrictMode>
|
|
398
|
-
<RouterProvider router={router} />
|
|
399
|
-
</StrictMode>,
|
|
400
|
-
)
|
|
401
|
-
}
|
|
291
|
+
\`\`\`sh
|
|
292
|
+
cd my-app
|
|
293
|
+
npm run dev
|
|
402
294
|
\`\`\`
|
|
403
295
|
|
|
404
|
-
|
|
296
|
+
With either approach, you can now start building your React application with TanStack Router!
|
|
405
297
|
|
|
406
298
|
# Devtools
|
|
407
299
|
|
|
@@ -593,37 +485,748 @@ function App() {
|
|
|
593
485
|
- Specifies a Shadow DOM target for the devtools.
|
|
594
486
|
- By default, devtool styles are applied to the \`<head>\` tag of the main document (light DOM). When a \`shadowDOMTarget\` is provided, styles will be applied within this Shadow DOM instead.
|
|
595
487
|
|
|
596
|
-
#
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
-
|
|
609
|
-
-
|
|
610
|
-
-
|
|
611
|
-
-
|
|
612
|
-
-
|
|
613
|
-
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
488
|
+
# How to Migrate from React Router v7
|
|
489
|
+
|
|
490
|
+
This guide provides a step-by-step process to migrate your application from React Router v7 to TanStack Router. We'll cover the complete migration process from removing React Router dependencies to implementing TanStack Router's type-safe routing patterns.
|
|
491
|
+
|
|
492
|
+
## Quick Start
|
|
493
|
+
|
|
494
|
+
**Time Required:** 2-4 hours depending on app complexity
|
|
495
|
+
**Difficulty:** Intermediate
|
|
496
|
+
**Prerequisites:** Basic React knowledge, existing React Router v7 app
|
|
497
|
+
|
|
498
|
+
### What You'll Accomplish
|
|
499
|
+
|
|
500
|
+
- Remove React Router v7 dependencies and components
|
|
501
|
+
- Install and configure TanStack Router
|
|
502
|
+
- Convert route definitions to file-based routing
|
|
503
|
+
- Update navigation components and hooks
|
|
504
|
+
- Implement type-safe routing patterns
|
|
505
|
+
- Handle search params and dynamic routes
|
|
506
|
+
- Migrate from React Router v7's new features to TanStack Router equivalents
|
|
507
|
+
|
|
508
|
+
---
|
|
509
|
+
|
|
510
|
+
## Complete Migration Process
|
|
511
|
+
|
|
512
|
+
### Step 1: Prepare for Migration
|
|
513
|
+
|
|
514
|
+
Before making any changes, prepare your environment and codebase:
|
|
515
|
+
|
|
516
|
+
**1.1 Create a backup branch**
|
|
517
|
+
|
|
518
|
+
\`\`\`bash
|
|
519
|
+
git checkout -b migrate-to-tanstack-router
|
|
520
|
+
git push -u origin migrate-to-tanstack-router
|
|
521
|
+
\`\`\`
|
|
522
|
+
|
|
523
|
+
**1.2 Install TanStack Router (keep React Router temporarily)**
|
|
524
|
+
|
|
525
|
+
\`\`\`bash
|
|
526
|
+
# Install TanStack Router
|
|
527
|
+
npm install @tanstack/react-router
|
|
528
|
+
|
|
529
|
+
# Install development dependencies
|
|
530
|
+
npm install -D @tanstack/router-plugin @tanstack/react-router-devtools
|
|
531
|
+
\`\`\`
|
|
532
|
+
|
|
533
|
+
**1.3 Set up the router plugin for your bundler**
|
|
534
|
+
|
|
535
|
+
For **Vite** users, update your \`vite.config.ts\`:
|
|
536
|
+
|
|
537
|
+
\`\`\`typescript
|
|
538
|
+
import { defineConfig } from 'vite'
|
|
539
|
+
import react from '@vitejs/plugin-react'
|
|
540
|
+
import { tanstackRouter } from '@tanstack/router-plugin/vite'
|
|
541
|
+
|
|
542
|
+
export default defineConfig({
|
|
543
|
+
plugins: [
|
|
544
|
+
tanstackRouter(), // Add this before react plugin
|
|
545
|
+
react(),
|
|
546
|
+
],
|
|
547
|
+
})
|
|
548
|
+
\`\`\`
|
|
549
|
+
|
|
550
|
+
For **other bundlers**, see our [bundler configuration guides](../routing/).
|
|
551
|
+
|
|
552
|
+
### Step 2: Create TanStack Router Configuration
|
|
553
|
+
|
|
554
|
+
**2.1 Create router configuration file**
|
|
555
|
+
|
|
556
|
+
Create \`tsr.config.json\` in your project root:
|
|
557
|
+
|
|
558
|
+
\`\`\`json
|
|
559
|
+
{
|
|
560
|
+
"routesDirectory": "./src/routes",
|
|
561
|
+
"generatedRouteTree": "./src/routeTree.gen.ts",
|
|
562
|
+
"quoteStyle": "single"
|
|
563
|
+
}
|
|
564
|
+
\`\`\`
|
|
565
|
+
|
|
566
|
+
**2.2 Create routes directory**
|
|
567
|
+
|
|
568
|
+
\`\`\`bash
|
|
569
|
+
mkdir src/routes
|
|
570
|
+
\`\`\`
|
|
571
|
+
|
|
572
|
+
### Step 3: Convert Your React Router v7 Structure
|
|
573
|
+
|
|
574
|
+
**3.1 Identify your current React Router v7 setup**
|
|
575
|
+
|
|
576
|
+
React Router v7 introduced several new patterns. Look for:
|
|
577
|
+
|
|
578
|
+
- \`createBrowserRouter\` with new data APIs
|
|
579
|
+
- Framework mode configurations
|
|
580
|
+
- Server-side rendering setup
|
|
581
|
+
- New \`loader\` and \`action\` functions
|
|
582
|
+
- \`defer\` usage (simplified in v7)
|
|
583
|
+
- Type-safe routing features
|
|
584
|
+
|
|
585
|
+
**3.2 Create root route**
|
|
586
|
+
|
|
587
|
+
Create \`src/routes/__root.tsx\`:
|
|
588
|
+
|
|
589
|
+
\`\`\`typescript
|
|
590
|
+
import { createRootRoute, Link, Outlet } from '@tanstack/react-router'
|
|
591
|
+
import { TanStackRouterDevtools } from '@tanstack/react-router-devtools'
|
|
592
|
+
|
|
593
|
+
export const Route = createRootRoute({
|
|
594
|
+
component: () => (
|
|
595
|
+
<>
|
|
596
|
+
{/* Your existing layout/navbar content */}
|
|
597
|
+
<div className="p-2 flex gap-2">
|
|
598
|
+
<Link to="/" className="[&.active]:font-bold">
|
|
599
|
+
Home
|
|
600
|
+
</Link>
|
|
601
|
+
<Link to="/about" className="[&.active]:font-bold">
|
|
602
|
+
About
|
|
603
|
+
</Link>
|
|
604
|
+
</div>
|
|
605
|
+
<hr />
|
|
606
|
+
<Outlet />
|
|
607
|
+
<TanStackRouterDevtools />
|
|
608
|
+
</>
|
|
609
|
+
),
|
|
610
|
+
})
|
|
611
|
+
\`\`\`
|
|
612
|
+
|
|
613
|
+
**3.3 Create index route**
|
|
614
|
+
|
|
615
|
+
Create \`src/routes/index.tsx\` for your home page:
|
|
616
|
+
|
|
617
|
+
\`\`\`typescript
|
|
618
|
+
import { createFileRoute } from '@tanstack/react-router'
|
|
619
|
+
|
|
620
|
+
export const Route = createFileRoute('/')({
|
|
621
|
+
component: Index,
|
|
622
|
+
})
|
|
623
|
+
|
|
624
|
+
function Index() {
|
|
625
|
+
return (
|
|
626
|
+
<div className="p-2">
|
|
627
|
+
<h3>Welcome Home!</h3>
|
|
628
|
+
</div>
|
|
629
|
+
)
|
|
630
|
+
}
|
|
631
|
+
\`\`\`
|
|
632
|
+
|
|
633
|
+
**3.4 Convert React Router v7 loaders**
|
|
634
|
+
|
|
635
|
+
React Router v7 simplified loader patterns. Here's how to migrate them:
|
|
636
|
+
|
|
637
|
+
**React Router v7:**
|
|
638
|
+
|
|
639
|
+
\`\`\`typescript
|
|
640
|
+
// app/routes/posts.tsx
|
|
641
|
+
export async function loader() {
|
|
642
|
+
const posts = await fetchPosts()
|
|
643
|
+
return { posts } // v7 removed need for json() wrapper
|
|
644
|
+
}
|
|
645
|
+
|
|
646
|
+
export default function Posts() {
|
|
647
|
+
const { posts } = useLoaderData()
|
|
648
|
+
return <div>{/* render posts */}</div>
|
|
649
|
+
}
|
|
650
|
+
\`\`\`
|
|
651
|
+
|
|
652
|
+
**TanStack Router equivalent:**
|
|
653
|
+
Create \`src/routes/posts.tsx\`:
|
|
654
|
+
|
|
655
|
+
\`\`\`typescript
|
|
656
|
+
import { createFileRoute } from '@tanstack/react-router'
|
|
657
|
+
|
|
658
|
+
export const Route = createFileRoute('/posts')({
|
|
659
|
+
loader: async () => {
|
|
660
|
+
const posts = await fetchPosts()
|
|
661
|
+
return { posts }
|
|
662
|
+
},
|
|
663
|
+
component: Posts,
|
|
664
|
+
})
|
|
665
|
+
|
|
666
|
+
function Posts() {
|
|
667
|
+
const { posts } = Route.useLoaderData()
|
|
668
|
+
return <div>{/* render posts */}</div>
|
|
669
|
+
}
|
|
670
|
+
\`\`\`
|
|
671
|
+
|
|
672
|
+
**3.5 Convert dynamic routes**
|
|
673
|
+
|
|
674
|
+
**React Router v7:**
|
|
675
|
+
|
|
676
|
+
\`\`\`typescript
|
|
677
|
+
// app/routes/posts.$postId.tsx
|
|
678
|
+
export async function loader({ params }) {
|
|
679
|
+
const post = await fetchPost(params.postId)
|
|
680
|
+
return { post }
|
|
681
|
+
}
|
|
682
|
+
|
|
683
|
+
export default function Post() {
|
|
684
|
+
const { post } = useLoaderData()
|
|
685
|
+
return <div>{post.title}</div>
|
|
686
|
+
}
|
|
687
|
+
\`\`\`
|
|
688
|
+
|
|
689
|
+
**TanStack Router equivalent:**
|
|
690
|
+
Create \`src/routes/posts/$postId.tsx\`:
|
|
691
|
+
|
|
692
|
+
\`\`\`typescript
|
|
693
|
+
import { createFileRoute } from '@tanstack/react-router'
|
|
694
|
+
|
|
695
|
+
export const Route = createFileRoute('/posts/$postId')({
|
|
696
|
+
loader: async ({ params }) => {
|
|
697
|
+
const post = await fetchPost(params.postId)
|
|
698
|
+
return { post }
|
|
699
|
+
},
|
|
700
|
+
component: Post,
|
|
701
|
+
})
|
|
702
|
+
|
|
703
|
+
function Post() {
|
|
704
|
+
const { post } = Route.useLoaderData()
|
|
705
|
+
const { postId } = Route.useParams()
|
|
706
|
+
return <div>{post.title}</div>
|
|
707
|
+
}
|
|
708
|
+
\`\`\`
|
|
709
|
+
|
|
710
|
+
**3.6 Convert React Router v7 actions**
|
|
711
|
+
|
|
712
|
+
**React Router v7:**
|
|
713
|
+
|
|
714
|
+
\`\`\`typescript
|
|
715
|
+
export async function action({ request, params }) {
|
|
716
|
+
const formData = await request.formData()
|
|
717
|
+
const result = await updatePost(params.postId, formData)
|
|
718
|
+
return { success: true }
|
|
719
|
+
}
|
|
720
|
+
\`\`\`
|
|
721
|
+
|
|
722
|
+
**TanStack Router equivalent:**
|
|
723
|
+
|
|
724
|
+
\`\`\`typescript
|
|
725
|
+
export const Route = createFileRoute('/posts/$postId/edit')({
|
|
726
|
+
component: EditPost,
|
|
727
|
+
// Actions are typically handled differently in TanStack Router
|
|
728
|
+
// Use mutations or form libraries like React Hook Form
|
|
729
|
+
})
|
|
730
|
+
|
|
731
|
+
function EditPost() {
|
|
732
|
+
const navigate = useNavigate()
|
|
733
|
+
|
|
734
|
+
const handleSubmit = async (formData) => {
|
|
735
|
+
const result = await updatePost(params.postId, formData)
|
|
736
|
+
navigate({ to: '/posts/$postId', params: { postId } })
|
|
737
|
+
}
|
|
738
|
+
|
|
739
|
+
return <form onSubmit={handleSubmit}>{/* form */}</form>
|
|
740
|
+
}
|
|
741
|
+
\`\`\`
|
|
742
|
+
|
|
743
|
+
### Step 4: Handle React Router v7 Framework Features
|
|
744
|
+
|
|
745
|
+
**4.1 Server-Side Rendering Migration**
|
|
746
|
+
|
|
747
|
+
React Router v7 introduced framework mode with SSR. If you're using this:
|
|
748
|
+
|
|
749
|
+
**React Router v7 Framework Mode:**
|
|
750
|
+
|
|
751
|
+
\`\`\`typescript
|
|
752
|
+
// react-router.config.ts
|
|
753
|
+
export default {
|
|
754
|
+
ssr: true,
|
|
755
|
+
prerender: ['/'],
|
|
756
|
+
}
|
|
757
|
+
\`\`\`
|
|
758
|
+
|
|
759
|
+
**TanStack Router approach:**
|
|
760
|
+
|
|
761
|
+
TanStack Router has built-in SSR capabilities. Set up your router for SSR:
|
|
762
|
+
|
|
763
|
+
\`\`\`typescript
|
|
764
|
+
// src/router.tsx
|
|
765
|
+
import { createRouter } from '@tanstack/react-router'
|
|
766
|
+
import { routeTree } from './routeTree.gen'
|
|
767
|
+
|
|
768
|
+
const router = createRouter({
|
|
769
|
+
routeTree,
|
|
770
|
+
context: {
|
|
771
|
+
// Add any SSR context here
|
|
772
|
+
},
|
|
773
|
+
})
|
|
774
|
+
|
|
775
|
+
declare module '@tanstack/react-router' {
|
|
776
|
+
interface Register {
|
|
777
|
+
router: typeof router
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
export { router }
|
|
782
|
+
\`\`\`
|
|
783
|
+
|
|
784
|
+
For server-side rendering, use TanStack Router's built-in SSR APIs:
|
|
785
|
+
|
|
786
|
+
\`\`\`typescript
|
|
787
|
+
// server.tsx
|
|
788
|
+
import { createMemoryHistory } from '@tanstack/react-router'
|
|
789
|
+
import { StartServer } from '@tanstack/start/server'
|
|
790
|
+
|
|
791
|
+
export async function render(url: string) {
|
|
792
|
+
const router = createRouter({
|
|
793
|
+
routeTree,
|
|
794
|
+
history: createMemoryHistory({ initialEntries: [url] }),
|
|
795
|
+
})
|
|
796
|
+
|
|
797
|
+
await router.load()
|
|
798
|
+
|
|
799
|
+
return (
|
|
800
|
+
<StartServer router={router} />
|
|
801
|
+
)
|
|
802
|
+
}
|
|
803
|
+
\`\`\`
|
|
804
|
+
|
|
805
|
+
**4.2 Code Splitting Migration**
|
|
806
|
+
|
|
807
|
+
React Router v7 improved code splitting. TanStack Router handles this via lazy routes:
|
|
808
|
+
|
|
809
|
+
**React Router v7:**
|
|
810
|
+
|
|
811
|
+
\`\`\`typescript
|
|
812
|
+
const LazyComponent = lazy(() => import('./LazyComponent'))
|
|
813
|
+
\`\`\`
|
|
814
|
+
|
|
815
|
+
**TanStack Router:**
|
|
816
|
+
|
|
817
|
+
\`\`\`typescript
|
|
818
|
+
import { createLazyFileRoute } from '@tanstack/react-router'
|
|
819
|
+
|
|
820
|
+
export const Route = createLazyFileRoute('/lazy-route')({
|
|
821
|
+
component: LazyComponent,
|
|
822
|
+
})
|
|
823
|
+
|
|
824
|
+
function LazyComponent() {
|
|
825
|
+
return <div>Lazy loaded!</div>
|
|
826
|
+
}
|
|
827
|
+
\`\`\`
|
|
828
|
+
|
|
829
|
+
### Step 5: Update Navigation Components
|
|
830
|
+
|
|
831
|
+
**5.1 Update Link components**
|
|
832
|
+
|
|
833
|
+
**React Router v7:**
|
|
834
|
+
|
|
835
|
+
\`\`\`typescript
|
|
836
|
+
import { Link } from 'react-router'
|
|
837
|
+
|
|
838
|
+
<Link to="/posts/123">View Post</Link>
|
|
839
|
+
<Link to="/posts" state={{ from: 'home' }}>Posts</Link>
|
|
840
|
+
\`\`\`
|
|
841
|
+
|
|
842
|
+
**TanStack Router:**
|
|
843
|
+
|
|
844
|
+
\`\`\`typescript
|
|
845
|
+
import { Link } from '@tanstack/react-router'
|
|
846
|
+
|
|
847
|
+
<Link to="/posts/$postId" params={{ postId: '123' }}>View Post</Link>
|
|
848
|
+
<Link to="/posts" state={{ from: 'home' }}>Posts</Link>
|
|
849
|
+
\`\`\`
|
|
850
|
+
|
|
851
|
+
**5.2 Update navigation hooks**
|
|
852
|
+
|
|
853
|
+
**React Router v7:**
|
|
854
|
+
|
|
855
|
+
\`\`\`typescript
|
|
856
|
+
import { useNavigate } from 'react-router'
|
|
857
|
+
|
|
858
|
+
function Component() {
|
|
859
|
+
const navigate = useNavigate()
|
|
860
|
+
|
|
861
|
+
const handleClick = () => {
|
|
862
|
+
navigate('/posts/123')
|
|
863
|
+
}
|
|
864
|
+
}
|
|
865
|
+
\`\`\`
|
|
866
|
+
|
|
867
|
+
**TanStack Router:**
|
|
868
|
+
|
|
869
|
+
\`\`\`typescript
|
|
870
|
+
import { useNavigate } from '@tanstack/react-router'
|
|
871
|
+
|
|
872
|
+
function Component() {
|
|
873
|
+
const navigate = useNavigate()
|
|
874
|
+
|
|
875
|
+
const handleClick = () => {
|
|
876
|
+
navigate({ to: '/posts/$postId', params: { postId: '123' } })
|
|
877
|
+
}
|
|
878
|
+
}
|
|
879
|
+
\`\`\`
|
|
880
|
+
|
|
881
|
+
### Step 6: Handle React Router v7 Specific Features
|
|
882
|
+
|
|
883
|
+
**6.1 Migrate simplified \`defer\` usage**
|
|
884
|
+
|
|
885
|
+
React Router v7 simplified defer by removing the wrapper function:
|
|
886
|
+
|
|
887
|
+
**React Router v7:**
|
|
888
|
+
|
|
889
|
+
\`\`\`typescript
|
|
890
|
+
export async function loader() {
|
|
891
|
+
return {
|
|
892
|
+
data: fetchData(), // Promise directly returned
|
|
893
|
+
}
|
|
894
|
+
}
|
|
895
|
+
\`\`\`
|
|
896
|
+
|
|
897
|
+
**TanStack Router:**
|
|
898
|
+
|
|
899
|
+
TanStack Router uses a different approach for deferred data. Use loading states:
|
|
900
|
+
|
|
901
|
+
\`\`\`typescript
|
|
902
|
+
export const Route = createFileRoute('/deferred')({
|
|
903
|
+
loader: async () => {
|
|
904
|
+
const data = await fetchData()
|
|
905
|
+
return { data }
|
|
906
|
+
},
|
|
907
|
+
pendingComponent: () => <div>Loading...</div>,
|
|
908
|
+
component: DeferredComponent,
|
|
909
|
+
})
|
|
910
|
+
\`\`\`
|
|
911
|
+
|
|
912
|
+
**6.2 Handle React Router v7's enhanced type safety**
|
|
913
|
+
|
|
914
|
+
React Router v7 improved type inference. TanStack Router provides even better type safety:
|
|
915
|
+
|
|
916
|
+
\`\`\`typescript
|
|
917
|
+
// TanStack Router automatically infers types
|
|
918
|
+
export const Route = createFileRoute('/posts/$postId')({
|
|
919
|
+
loader: async ({ params }) => {
|
|
920
|
+
// params.postId is automatically typed as string
|
|
921
|
+
const post = await fetchPost(params.postId)
|
|
922
|
+
return { post }
|
|
923
|
+
},
|
|
924
|
+
component: Post,
|
|
925
|
+
})
|
|
926
|
+
|
|
927
|
+
function Post() {
|
|
928
|
+
// post is automatically typed based on loader return
|
|
929
|
+
const { post } = Route.useLoaderData()
|
|
930
|
+
// postId is automatically typed as string
|
|
931
|
+
const { postId } = Route.useParams()
|
|
932
|
+
}
|
|
933
|
+
\`\`\`
|
|
934
|
+
|
|
935
|
+
### Step 7: Update Your Main Router Setup
|
|
936
|
+
|
|
937
|
+
**7.1 Replace React Router v7 router creation**
|
|
938
|
+
|
|
939
|
+
**Before (React Router v7):**
|
|
940
|
+
|
|
941
|
+
\`\`\`typescript
|
|
942
|
+
import { createBrowserRouter, RouterProvider } from 'react-router'
|
|
943
|
+
|
|
944
|
+
const router = createBrowserRouter([
|
|
945
|
+
// Your route definitions
|
|
946
|
+
])
|
|
947
|
+
|
|
948
|
+
ReactDOM.createRoot(document.getElementById('root')!).render(
|
|
949
|
+
<React.StrictMode>
|
|
950
|
+
<RouterProvider router={router} />
|
|
951
|
+
</React.StrictMode>,
|
|
952
|
+
)
|
|
953
|
+
\`\`\`
|
|
954
|
+
|
|
955
|
+
**After (TanStack Router):**
|
|
956
|
+
|
|
957
|
+
\`\`\`typescript
|
|
958
|
+
import { RouterProvider } from '@tanstack/react-router'
|
|
959
|
+
import { router } from './router'
|
|
960
|
+
|
|
961
|
+
ReactDOM.createRoot(document.getElementById('root')!).render(
|
|
962
|
+
<React.StrictMode>
|
|
963
|
+
<RouterProvider router={router} />
|
|
964
|
+
</React.StrictMode>,
|
|
965
|
+
)
|
|
966
|
+
\`\`\`
|
|
967
|
+
|
|
968
|
+
### Step 8: Handle Search Parameters
|
|
969
|
+
|
|
970
|
+
**8.1 React Router v7 to TanStack Router search params**
|
|
971
|
+
|
|
972
|
+
**React Router v7:**
|
|
973
|
+
|
|
974
|
+
\`\`\`typescript
|
|
975
|
+
import { useSearchParams } from 'react-router'
|
|
976
|
+
|
|
977
|
+
function Component() {
|
|
978
|
+
const [searchParams, setSearchParams] = useSearchParams()
|
|
979
|
+
const page = searchParams.get('page') || '1'
|
|
980
|
+
|
|
981
|
+
const updatePage = (newPage) => {
|
|
982
|
+
setSearchParams({ page: newPage })
|
|
983
|
+
}
|
|
984
|
+
}
|
|
985
|
+
\`\`\`
|
|
986
|
+
|
|
987
|
+
**TanStack Router:**
|
|
988
|
+
|
|
989
|
+
\`\`\`typescript
|
|
990
|
+
import { createFileRoute } from '@tanstack/react-router'
|
|
991
|
+
import { z } from 'zod'
|
|
992
|
+
|
|
993
|
+
const searchSchema = z.object({
|
|
994
|
+
page: z.number().catch(1),
|
|
995
|
+
filter: z.string().optional(),
|
|
996
|
+
})
|
|
997
|
+
|
|
998
|
+
export const Route = createFileRoute('/posts')({
|
|
999
|
+
validateSearch: searchSchema,
|
|
1000
|
+
component: Posts,
|
|
1001
|
+
})
|
|
1002
|
+
|
|
1003
|
+
function Posts() {
|
|
1004
|
+
const navigate = useNavigate({ from: '/posts' })
|
|
1005
|
+
const { page, filter } = Route.useSearch()
|
|
1006
|
+
|
|
1007
|
+
const updatePage = (newPage: number) => {
|
|
1008
|
+
navigate({ search: (prev) => ({ ...prev, page: newPage }) })
|
|
1009
|
+
}
|
|
1010
|
+
}
|
|
1011
|
+
\`\`\`
|
|
1012
|
+
|
|
1013
|
+
### Step 9: Remove React Router Dependencies
|
|
1014
|
+
|
|
1015
|
+
Only after everything is working with TanStack Router:
|
|
1016
|
+
|
|
1017
|
+
**9.1 Remove React Router v7**
|
|
1018
|
+
|
|
1019
|
+
\`\`\`bash
|
|
1020
|
+
npm uninstall react-router
|
|
1021
|
+
\`\`\`
|
|
1022
|
+
|
|
1023
|
+
**9.2 Clean up unused imports**
|
|
1024
|
+
|
|
1025
|
+
Search your codebase for any remaining React Router imports:
|
|
1026
|
+
|
|
1027
|
+
\`\`\`bash
|
|
1028
|
+
# Find remaining React Router imports
|
|
1029
|
+
grep -r "react-router" src/
|
|
1030
|
+
\`\`\`
|
|
1031
|
+
|
|
1032
|
+
Remove any remaining imports and replace with TanStack Router equivalents.
|
|
1033
|
+
|
|
1034
|
+
### Step 10: Add Advanced Type Safety
|
|
1035
|
+
|
|
1036
|
+
**10.1 Configure strict TypeScript**
|
|
1037
|
+
|
|
1038
|
+
Update your \`tsconfig.json\`:
|
|
1039
|
+
|
|
1040
|
+
\`\`\`json
|
|
1041
|
+
{
|
|
1042
|
+
"compilerOptions": {
|
|
1043
|
+
"strict": true,
|
|
1044
|
+
"noUncheckedIndexedAccess": true
|
|
1045
|
+
}
|
|
1046
|
+
}
|
|
1047
|
+
\`\`\`
|
|
1048
|
+
|
|
1049
|
+
**10.2 Add search parameter validation**
|
|
1050
|
+
|
|
1051
|
+
For routes with search parameters, add validation schemas:
|
|
1052
|
+
|
|
1053
|
+
\`\`\`typescript
|
|
1054
|
+
import { createFileRoute } from '@tanstack/react-router'
|
|
1055
|
+
import { z } from 'zod'
|
|
1056
|
+
|
|
1057
|
+
const postsSearchSchema = z.object({
|
|
1058
|
+
page: z.number().min(1).catch(1),
|
|
1059
|
+
search: z.string().optional(),
|
|
1060
|
+
category: z.enum(['tech', 'business', 'lifestyle']).optional(),
|
|
1061
|
+
})
|
|
1062
|
+
|
|
1063
|
+
export const Route = createFileRoute('/posts')({
|
|
1064
|
+
validateSearch: postsSearchSchema,
|
|
1065
|
+
component: Posts,
|
|
1066
|
+
})
|
|
1067
|
+
\`\`\`
|
|
1068
|
+
|
|
1069
|
+
---
|
|
1070
|
+
|
|
1071
|
+
## Production Checklist
|
|
1072
|
+
|
|
1073
|
+
Before deploying your migrated application:
|
|
1074
|
+
|
|
1075
|
+
### Router Configuration
|
|
1076
|
+
|
|
1077
|
+
- [ ] Router instance created and properly exported
|
|
1078
|
+
- [ ] Route tree generated successfully
|
|
1079
|
+
- [ ] TypeScript declarations registered
|
|
1080
|
+
- [ ] All route files follow naming conventions
|
|
1081
|
+
|
|
1082
|
+
### Route Migration
|
|
1083
|
+
|
|
1084
|
+
- [ ] All React Router v7 routes converted to file-based routing
|
|
1085
|
+
- [ ] Dynamic routes updated with proper parameter syntax
|
|
1086
|
+
- [ ] Nested routes maintain hierarchy
|
|
1087
|
+
- [ ] Index routes created where needed
|
|
1088
|
+
- [ ] Layout routes preserve component structure
|
|
1089
|
+
|
|
1090
|
+
### Feature Migration
|
|
1091
|
+
|
|
1092
|
+
- [ ] All React Router v7 loaders converted
|
|
1093
|
+
- [ ] Actions migrated to appropriate patterns
|
|
1094
|
+
- [ ] Server-side rendering configured (if applicable)
|
|
1095
|
+
- [ ] Code splitting implemented
|
|
1096
|
+
- [ ] Type safety enhanced
|
|
1097
|
+
|
|
1098
|
+
### Navigation Updates
|
|
1099
|
+
|
|
1100
|
+
- [ ] All Link components updated to TanStack Router
|
|
1101
|
+
- [ ] useNavigate hooks replaced and tested
|
|
1102
|
+
- [ ] Navigation parameters properly typed
|
|
1103
|
+
- [ ] Search parameter validation implemented
|
|
1104
|
+
|
|
1105
|
+
### Code Cleanup
|
|
1106
|
+
|
|
1107
|
+
- [ ] React Router v7 dependencies removed
|
|
1108
|
+
- [ ] Unused imports cleaned up
|
|
1109
|
+
- [ ] No React Router references remain
|
|
1110
|
+
- [ ] TypeScript compilation successful
|
|
1111
|
+
- [ ] All tests passing
|
|
1112
|
+
|
|
1113
|
+
### Testing
|
|
1114
|
+
|
|
1115
|
+
- [ ] All routes accessible and rendering correctly
|
|
1116
|
+
- [ ] Navigation between routes working
|
|
1117
|
+
- [ ] Back/forward browser buttons functional
|
|
1118
|
+
- [ ] Search parameters persisting correctly
|
|
1119
|
+
- [ ] Dynamic routes with parameters working
|
|
1120
|
+
- [ ] Nested route layouts displaying properly
|
|
1121
|
+
- [ ] Framework features (SSR, code splitting) working if applicable
|
|
1122
|
+
|
|
1123
|
+
---
|
|
1124
|
+
|
|
1125
|
+
## Common Problems
|
|
1126
|
+
|
|
1127
|
+
### Error: "Cannot use useNavigate outside of context"
|
|
1128
|
+
|
|
1129
|
+
**Problem:** You have remaining React Router imports that conflict with TanStack Router.
|
|
1130
|
+
|
|
1131
|
+
**Solution:**
|
|
1132
|
+
|
|
1133
|
+
1. Search for all React Router imports:
|
|
1134
|
+
\`\`\`bash
|
|
1135
|
+
grep -r "react-router" src/
|
|
1136
|
+
\`\`\`
|
|
1137
|
+
2. Replace all imports with TanStack Router equivalents
|
|
1138
|
+
3. Ensure React Router is completely uninstalled
|
|
1139
|
+
|
|
1140
|
+
### TypeScript Errors: Route Parameters
|
|
1141
|
+
|
|
1142
|
+
**Problem:** TypeScript showing errors about route parameters not being typed correctly.
|
|
1143
|
+
|
|
1144
|
+
**Solution:**
|
|
1145
|
+
|
|
1146
|
+
1. Ensure your router is registered in the TypeScript module declaration:
|
|
1147
|
+
\`\`\`typescript
|
|
1148
|
+
declare module '@tanstack/react-router' {
|
|
1149
|
+
interface Register {
|
|
1150
|
+
router: typeof router
|
|
1151
|
+
}
|
|
1152
|
+
}
|
|
1153
|
+
\`\`\`
|
|
1154
|
+
2. Check that your route files export the Route correctly
|
|
1155
|
+
3. Verify parameter names match between route definition and usage
|
|
1156
|
+
|
|
1157
|
+
### React Router v7 Framework Features Not Working
|
|
1158
|
+
|
|
1159
|
+
**Problem:** Missing SSR or code splitting functionality after migration.
|
|
1160
|
+
|
|
1161
|
+
**Solution:**
|
|
1162
|
+
|
|
1163
|
+
1. TanStack Router has built-in SSR capabilities - use TanStack Start for full-stack applications
|
|
1164
|
+
2. Use TanStack Router's lazy routes for code splitting
|
|
1165
|
+
3. Configure SSR using TanStack Router's native APIs
|
|
1166
|
+
4. Follow the [SSR setup guide](../setup-ssr.md) for detailed instructions
|
|
1167
|
+
|
|
1168
|
+
### Routes Not Matching
|
|
1169
|
+
|
|
1170
|
+
**Problem:** Routes not rendering or 404 errors for valid routes.
|
|
1171
|
+
|
|
1172
|
+
**Solution:**
|
|
1173
|
+
|
|
1174
|
+
1. Check file naming follows TanStack Router conventions:
|
|
1175
|
+
- Dynamic routes: \`$paramName.tsx\`
|
|
1176
|
+
- Index routes: \`index.tsx\`
|
|
1177
|
+
- Nested routes: proper directory structure
|
|
1178
|
+
2. Verify route tree generation is working
|
|
1179
|
+
3. Check that the router plugin is properly configured
|
|
1180
|
+
|
|
1181
|
+
### React Router v7 Simplified APIs Not Translating
|
|
1182
|
+
|
|
1183
|
+
**Problem:** v7's simplified \`defer\` or other features don't have direct equivalents.
|
|
1184
|
+
|
|
1185
|
+
**Solution:**
|
|
1186
|
+
|
|
1187
|
+
1. Use TanStack Router's pending states for loading UX
|
|
1188
|
+
2. Implement data fetching patterns that fit TanStack Router's architecture
|
|
1189
|
+
3. Leverage TanStack Router's superior type safety for better DX
|
|
1190
|
+
|
|
1191
|
+
---
|
|
1192
|
+
|
|
1193
|
+
## React Router v7 vs TanStack Router Feature Comparison
|
|
1194
|
+
|
|
1195
|
+
| Feature | React Router v7 | TanStack Router |
|
|
1196
|
+
| ------------------ | ------------------- | ---------------------------- |
|
|
1197
|
+
| Type Safety | Good | Excellent |
|
|
1198
|
+
| File-based Routing | Framework mode only | Built-in |
|
|
1199
|
+
| Search Params | Basic | Validated with schemas |
|
|
1200
|
+
| Code Splitting | Good | Excellent with lazy routes |
|
|
1201
|
+
| SSR | Framework mode | Built-in with TanStack Start |
|
|
1202
|
+
| Bundle Size | Larger | Smaller |
|
|
1203
|
+
| Learning Curve | Moderate | Moderate |
|
|
1204
|
+
| Community | Large | Growing |
|
|
1205
|
+
|
|
1206
|
+
---
|
|
1207
|
+
|
|
1208
|
+
## Common Next Steps
|
|
1209
|
+
|
|
1210
|
+
After successfully migrating to TanStack Router, consider these enhancements:
|
|
1211
|
+
|
|
1212
|
+
### Advanced Features to Explore
|
|
1213
|
+
|
|
1214
|
+
- **Route-based code splitting** - Improve performance with lazy loading
|
|
1215
|
+
- **Search parameter validation** - Type-safe URL state management
|
|
1216
|
+
- **Route preloading** - Enhance perceived performance
|
|
1217
|
+
- **Route masking** - Advanced URL management
|
|
1218
|
+
- **Integration with TanStack Query** - Powerful data fetching
|
|
1219
|
+
|
|
1220
|
+
---
|
|
1221
|
+
|
|
1222
|
+
## Related Resources
|
|
1223
|
+
|
|
1224
|
+
- [TanStack Router Documentation](https://tanstack.com/router) - Complete API reference
|
|
1225
|
+
- [File-Based Routing Guide](../../routing/file-based-routing.md) - Detailed routing concepts
|
|
1226
|
+
- [Navigation Guide](../../guide/navigation.md) - Complete navigation patterns
|
|
1227
|
+
- [Search Parameters Guide](../../guide/search-params.md) - Advanced search param usage
|
|
1228
|
+
- [Type Safety Guide](../../guide/type-safety.md) - TypeScript integration details
|
|
1229
|
+
- [React Router v7 Changelog](https://reactrouter.com/start/changelog) - What changed in v7
|
|
627
1230
|
|
|
628
1231
|
# Migration from React Location
|
|
629
1232
|
|
|
@@ -895,6 +1498,20 @@ If you are facing any issues or have any questions, feel free to ask for help in
|
|
|
895
1498
|
|
|
896
1499
|
Welcome to the TanStack Router FAQ! Here you'll find answers to common questions about the TanStack Router. If you have a question that isn't answered here, please feel free to ask in the [TanStack Discord](https://tlinz.com/discord).
|
|
897
1500
|
|
|
1501
|
+
## Why should you choose TanStack Router over another router?
|
|
1502
|
+
|
|
1503
|
+
To answer this question, it's important to view the other options in the space. There are many alternatives to choose from, but only a couple that are widely adopted and actively maintained:
|
|
1504
|
+
|
|
1505
|
+
- **Next.js** - Widely regarded as the leading framework for starting new React projects. Its design focuses on performance, development workflows, and cutting-edge technology. The framework's APIs and abstractions, while powerful, can sometimes present as non-standard. Rapid growth and industry adoption have resulted in a feature-rich experience, sometimes leading to a steeper learning curve and increased overhead.
|
|
1506
|
+
- **Remix / React Router** - Based on the historically successful React Router, Remix delivers a powerful developer and user experience. Its API and architectural vision are firmly rooted in web standards such as Request/Response, with an emphasis on adaptability across various JavaScript environments. Many of its APIs and abstractions are well-designed and have influenced more than a few of TanStack Router's APIs. However, its rigid design, the integration of type safety as an add-on, and sometimes strict adherence to platform APIs can present limitations for some developers.
|
|
1507
|
+
|
|
1508
|
+
These frameworks and routers have their strengths, but they also come with trade-offs that may not align with every project's needs. TanStack Router aims to strike a balance by offering routing APIs designed to improve the developer experience without sacrificing flexibility or performance.
|
|
1509
|
+
|
|
1510
|
+
## Is TanStack Router a framework?
|
|
1511
|
+
|
|
1512
|
+
TanStack Router itself is not a "framework" in the traditional sense, since it doesn't address a few other common full-stack concerns. However, TanStack Router has been designed to be upgradable to a full-stack framework when used in conjunction with other tools that address bundling, deployments, and server-side-specific functionality. This is why we are currently developing [TanStack Start](https://tanstack.com/start), a full-stack framework that is built on top of TanStack Router and Vite.
|
|
1513
|
+
For a deeper dive on the history of TanStack Router, feel free to read [TanStack Router's History](../decisions-on-dx.md#tanstack-routers-origin-story).
|
|
1514
|
+
|
|
898
1515
|
## Should I commit my \`routeTree.gen.ts\` file into git?
|
|
899
1516
|
|
|
900
1517
|
Yes! Although the route tree file (i.e., \`routeTree.gen.ts\`) is generated by TanStack Router, it is essentially part of your application’s runtime, not a build artifact. The route tree file is a critical part of your application’s source code, and it is used by TanStack Router to build your application’s routes at runtime.
|