@tanstack/react-router 1.132.47 → 1.133.7
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/cjs/Matches.cjs +4 -1
- package/dist/cjs/Matches.cjs.map +1 -1
- package/dist/esm/Matches.js +5 -2
- package/dist/esm/Matches.js.map +1 -1
- package/dist/llms/index.js +8 -0
- package/dist/llms/rules/guide.d.ts +1 -1
- package/dist/llms/rules/guide.js +14 -7
- package/dist/llms/rules/installation.d.ts +2 -0
- package/dist/llms/rules/installation.js +968 -0
- 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 +307 -463
- package/package.json +22 -4
- package/src/Matches.tsx +7 -3
|
@@ -161,247 +161,375 @@ 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.
|
|
176
|
+
|
|
177
|
+
[//]: # 'Requirements'
|
|
175
178
|
|
|
176
|
-
|
|
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.
|
|
177
180
|
|
|
178
|
-
|
|
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).
|
|
179
182
|
|
|
180
|
-
|
|
183
|
+
### Download and Install
|
|
181
184
|
|
|
182
|
-
|
|
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/react-router
|
|
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/react-router
|
|
190
191
|
# or
|
|
191
|
-
|
|
192
|
-
|
|
192
|
+
pnpm add @tanstack/react-router
|
|
193
|
+
#or
|
|
194
|
+
yarn add @tanstack/react-router
|
|
193
195
|
# or
|
|
194
|
-
bun add @tanstack/react-router
|
|
195
|
-
bun add -D @tanstack/router-plugin
|
|
196
|
+
bun add @tanstack/react-router
|
|
196
197
|
# or
|
|
197
|
-
deno add npm:@tanstack/react-router
|
|
198
|
+
deno add npm:@tanstack/react-router
|
|
198
199
|
\`\`\`
|
|
199
200
|
|
|
200
|
-
|
|
201
|
+
[//]: # 'installCommand'
|
|
201
202
|
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
tanstackRouter({
|
|
213
|
-
target: 'react',
|
|
214
|
-
autoCodeSplitting: true,
|
|
215
|
-
}),
|
|
216
|
-
react(),
|
|
217
|
-
// ...,
|
|
218
|
-
],
|
|
219
|
-
})
|
|
203
|
+
Once installed, you can verify the installation by checking your \`package.json\` file for the dependency.
|
|
204
|
+
|
|
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
|
-
|
|
231
|
+
[//]: # 'createAppCommand'
|
|
258
232
|
|
|
259
|
-
|
|
260
|
-
import { createFileRoute } from '@tanstack/react-router'
|
|
233
|
+
The CLI will guide you through a short series of prompts to customize your setup, including options for:
|
|
261
234
|
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
235
|
+
[//]: # 'CLIPrompts'
|
|
236
|
+
|
|
237
|
+
- File-based or code-based route configuration
|
|
238
|
+
- TypeScript support
|
|
239
|
+
- Tailwind CSS integration
|
|
240
|
+
- Toolchain setup
|
|
241
|
+
- Git initialization
|
|
242
|
+
|
|
243
|
+
[//]: # 'CLIPrompts'
|
|
244
|
+
|
|
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:
|
|
246
|
+
|
|
247
|
+
\`\`\`sh
|
|
248
|
+
cd your-project-name
|
|
249
|
+
npm run dev
|
|
250
|
+
\`\`\`
|
|
251
|
+
|
|
252
|
+
### Routing Options
|
|
253
|
+
|
|
254
|
+
TanStack Router supports both file-based and code-based route configurations, allowing you to choose the approach that best fits your workflow.
|
|
255
|
+
|
|
256
|
+
#### File-Based Route Generation
|
|
257
|
+
|
|
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.
|
|
259
|
+
|
|
260
|
+
To create a new project using file-based route generation, run the following command:
|
|
261
|
+
|
|
262
|
+
[//]: # 'createAppCommandFileBased'
|
|
263
|
+
|
|
264
|
+
\`\`\`sh
|
|
265
|
+
npx create-tsrouter-app@latest my-app --template file-router
|
|
266
|
+
\`\`\`
|
|
267
|
+
|
|
268
|
+
[//]: # 'createAppCommandFileBased'
|
|
269
|
+
|
|
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:
|
|
271
|
+
|
|
272
|
+
\`\`\`sh
|
|
273
|
+
cd my-app
|
|
274
|
+
npm run dev
|
|
275
|
+
\`\`\`
|
|
276
|
+
|
|
277
|
+
#### Code-Based Route Configuration
|
|
278
|
+
|
|
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.
|
|
280
|
+
|
|
281
|
+
[//]: # 'createAppCommandCodeBased'
|
|
282
|
+
|
|
283
|
+
\`\`\`sh
|
|
284
|
+
npx create-tsrouter-app@latest my-app
|
|
285
|
+
\`\`\`
|
|
286
|
+
|
|
287
|
+
[//]: # 'createAppCommandCodeBased'
|
|
288
|
+
|
|
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:
|
|
290
|
+
|
|
291
|
+
\`\`\`sh
|
|
292
|
+
cd my-app
|
|
293
|
+
npm run dev
|
|
294
|
+
\`\`\`
|
|
295
|
+
|
|
296
|
+
With either approach, you can now start building your React application with TanStack Router!
|
|
297
|
+
|
|
298
|
+
# Decisions on Developer Experience
|
|
299
|
+
|
|
300
|
+
When people first start using TanStack Router, they often have a lot of questions that revolve around the following themes:
|
|
301
|
+
|
|
302
|
+
> Why do I have to do things this way?
|
|
303
|
+
|
|
304
|
+
> Why is it done this way? and not that way?
|
|
305
|
+
|
|
306
|
+
> I'm used to doing it this way, why should I change?
|
|
307
|
+
|
|
308
|
+
And they are all valid questions. For the most part, people are used to using routing libraries that are very similar to each other. They all have a similar API, similar concepts, and similar ways of doing things.
|
|
309
|
+
|
|
310
|
+
But TanStack Router is different. It's not your average routing library. It's not your average state management library. It's not your average anything.
|
|
311
|
+
|
|
312
|
+
## TanStack Router's origin story
|
|
313
|
+
|
|
314
|
+
It's important to remember that TanStack Router's origins stem from [Nozzle.io](https://nozzle.io)'s need for a client-side routing solution that offered a first-in-class _URL Search Parameters_ experience without compromising on the **_type-safety_** that was required to power its complex dashboards.
|
|
315
|
+
|
|
316
|
+
And so, from TanStack Router's very inception, every facet of its design was meticulously thought out to ensure that its type-safety and developer experience were second to none.
|
|
317
|
+
|
|
318
|
+
## How does TanStack Router achieve this?
|
|
319
|
+
|
|
320
|
+
> TypeScript! TypeScript! TypeScript!
|
|
321
|
+
|
|
322
|
+
Every aspect of TanStack Router is designed to be as type-safe as possible, and this is achieved by leveraging TypeScript's type system to its fullest extent. This involves using some very advanced and complex types, type inference, and other features to ensure that the developer experience is as smooth as possible.
|
|
323
|
+
|
|
324
|
+
But to achieve this, we had to make some decisions that deviate from the norms in the routing world.
|
|
325
|
+
|
|
326
|
+
1. [**Route configuration boilerplate?**](#1-why-is-the-routers-configuration-done-this-way): You have to define your routes in a way that allows TypeScript to infer the types of your routes as much as possible.
|
|
327
|
+
2. [**TypeScript module declaration for the router?**](#2-declaring-the-router-instance-for-type-inference): You have to pass the \`Router\` instance to the rest of your application using TypeScript's module declaration.
|
|
328
|
+
3. [**Why push for file-based routing over code-based?**](#3-why-is-file-based-routing-the-preferred-way-to-define-routes): We push for file-based routing as the preferred way to define your routes.
|
|
329
|
+
|
|
330
|
+
> TLDR; All the design decisions in the developer experience of using TanStack Router are made so that you can have a best-in-class type-safety experience without compromising on the control, flexibility, and maintainability of your route configurations.
|
|
331
|
+
|
|
332
|
+
## 1. Why is the Router's configuration done this way?
|
|
265
333
|
|
|
266
|
-
|
|
334
|
+
When you want to leverage the TypeScript's inference features to its fullest, you'll quickly realize that _Generics_ are your best friend. And so, TanStack Router uses Generics everywhere to ensure that the types of your routes are inferred as much as possible.
|
|
335
|
+
|
|
336
|
+
This means that you have to define your routes in a way that allows TypeScript to infer the types of your routes as much as possible.
|
|
337
|
+
|
|
338
|
+
> Can I use JSX to define my routes?
|
|
339
|
+
|
|
340
|
+
Using JSX for defining your routes is **out of the question**, as TypeScript will not be able to infer the route configuration types of your router.
|
|
341
|
+
|
|
342
|
+
\`\`\`tsx
|
|
343
|
+
// ⛔️ This is not possible
|
|
344
|
+
function App() {
|
|
267
345
|
return (
|
|
268
|
-
<
|
|
269
|
-
<
|
|
270
|
-
|
|
346
|
+
<Router>
|
|
347
|
+
<Route path="/posts" component={PostsPage} />
|
|
348
|
+
<Route path="/posts/$postId" component={PostIdPage} />
|
|
349
|
+
{/* ... */}
|
|
350
|
+
</Router>
|
|
351
|
+
// ^? TypeScript cannot infer the routes in this configuration
|
|
271
352
|
)
|
|
272
353
|
}
|
|
273
354
|
\`\`\`
|
|
274
355
|
|
|
275
|
-
|
|
356
|
+
And since this would mean that you'd have to manually type the \`to\` prop of the \`<Link>\` component and wouldn't catch any errors until runtime, it's not a viable option.
|
|
276
357
|
|
|
277
|
-
|
|
278
|
-
import { createFileRoute } from '@tanstack/react-router'
|
|
358
|
+
> Maybe I could define my routes as a tree of nested objects?
|
|
279
359
|
|
|
280
|
-
|
|
281
|
-
|
|
360
|
+
\`\`\`tsx
|
|
361
|
+
// ⛔️ This file will just keep growing and growing...
|
|
362
|
+
const router = createRouter({
|
|
363
|
+
routes: {
|
|
364
|
+
posts: {
|
|
365
|
+
component: PostsPage, // /posts
|
|
366
|
+
children: {
|
|
367
|
+
$postId: {
|
|
368
|
+
component: PostIdPage, // /posts/$postId
|
|
369
|
+
},
|
|
370
|
+
},
|
|
371
|
+
},
|
|
372
|
+
// ...
|
|
373
|
+
},
|
|
282
374
|
})
|
|
283
|
-
|
|
284
|
-
function About() {
|
|
285
|
-
return <div className="p-2">Hello from About!</div>
|
|
286
|
-
}
|
|
287
375
|
\`\`\`
|
|
288
376
|
|
|
289
|
-
|
|
377
|
+
At first glance, this seems like a good idea. It's easy to visualize the entire route hierarchy in one go. But this approach has a couple of big downsides that make it not ideal for large applications:
|
|
378
|
+
|
|
379
|
+
- **It's not very scalable**: As your application grows, the tree will grow and become harder to manage. And since it's all defined in one file, it can become very hard to maintain.
|
|
380
|
+
- **It's not great for code-splitting**: You'd have to manually code-split each component and then pass it into the \`component\` property of the route, further complicating the route configuration with an ever-growing route configuration file.
|
|
381
|
+
|
|
382
|
+
This only gets worse as you begin to use more features of the router, such as nested context, loaders, search param validation, etc.
|
|
383
|
+
|
|
384
|
+
> So, what's the best way to define my routes?
|
|
385
|
+
|
|
386
|
+
What we found to be the best way to define your routes is to abstract the definition of the route configuration outside of the route-tree. Then stitch together your route configurations into a single cohesive route-tree that is then passed into the \`createRouter\` function.
|
|
290
387
|
|
|
291
|
-
|
|
388
|
+
You can read more about [code-based routing](../routing/code-based-routing.md) to see how to define your routes in this way.
|
|
292
389
|
|
|
293
|
-
|
|
390
|
+
> [!TIP]
|
|
391
|
+
> Finding Code-based routing to be a bit too cumbersome? See why [file-based routing](#3-why-is-file-based-routing-the-preferred-way-to-define-routes) is the preferred way to define your routes.
|
|
392
|
+
|
|
393
|
+
## 2. Declaring the Router instance for type inference
|
|
394
|
+
|
|
395
|
+
> Why do I have to declare the \`Router\`?
|
|
396
|
+
|
|
397
|
+
> This declaration stuff is way too complicated for me...
|
|
398
|
+
|
|
399
|
+
Once you've constructed your routes into a tree and passed it into your Router instance (using \`createRouter\`) with all the generics working correctly, you then need to somehow pass this information to the rest of your application.
|
|
400
|
+
|
|
401
|
+
There were two approaches we considered for this:
|
|
402
|
+
|
|
403
|
+
1. **Imports**: You could import the \`Router\` instance from the file where you created it and use it directly in your components.
|
|
294
404
|
|
|
295
405
|
\`\`\`tsx
|
|
296
|
-
import {
|
|
297
|
-
|
|
298
|
-
|
|
406
|
+
import { router } from '@/src/app'
|
|
407
|
+
export const PostsIdLink = () => {
|
|
408
|
+
return (
|
|
409
|
+
<Link<typeof router> to="/posts/$postId" params={{ postId: '123' }}>
|
|
410
|
+
Go to post 123
|
|
411
|
+
</Link>
|
|
412
|
+
)
|
|
413
|
+
}
|
|
414
|
+
\`\`\`
|
|
415
|
+
|
|
416
|
+
A downside to this approach is that you'd have to import the entire \`Router\` instance into every file where you want to use it. This can lead to increased bundle sizes and can be cumbersome to manage, and only get worse as your application grows and you use more features of the router.
|
|
299
417
|
|
|
300
|
-
|
|
301
|
-
import { routeTree } from './routeTree.gen'
|
|
418
|
+
2. **Module declaration**: You can use TypeScript's module declaration to declare the \`Router\` instance as a module that can be used for type inference anywhere in your application without having to import it.
|
|
302
419
|
|
|
303
|
-
|
|
304
|
-
const router = createRouter({ routeTree })
|
|
420
|
+
You'll do this once in your application.
|
|
305
421
|
|
|
306
|
-
|
|
422
|
+
\`\`\`tsx
|
|
423
|
+
// src/app.tsx
|
|
307
424
|
declare module '@tanstack/react-router' {
|
|
308
425
|
interface Register {
|
|
309
426
|
router: typeof router
|
|
310
427
|
}
|
|
311
428
|
}
|
|
429
|
+
\`\`\`
|
|
312
430
|
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
<
|
|
319
|
-
|
|
320
|
-
|
|
431
|
+
And then you can benefit from its auto-complete anywhere in your app without having to import it.
|
|
432
|
+
|
|
433
|
+
\`\`\`tsx
|
|
434
|
+
export const PostsIdLink = () => {
|
|
435
|
+
return (
|
|
436
|
+
<Link
|
|
437
|
+
to="/posts/$postId"
|
|
438
|
+
// ^? TypeScript will auto-complete this for you
|
|
439
|
+
params={{ postId: '123' }} // and this too!
|
|
440
|
+
>
|
|
441
|
+
Go to post 123
|
|
442
|
+
</Link>
|
|
321
443
|
)
|
|
322
444
|
}
|
|
323
445
|
\`\`\`
|
|
324
446
|
|
|
325
|
-
|
|
447
|
+
We went with **module declaration**, as it is what we found to be the most scalable and maintainable approach with the least amount of overhead and boilerplate.
|
|
326
448
|
|
|
327
|
-
##
|
|
449
|
+
## 3. Why is file-based routing the preferred way to define routes?
|
|
328
450
|
|
|
329
|
-
>
|
|
330
|
-
|
|
451
|
+
> Why are the docs pushing for file-based routing?
|
|
452
|
+
|
|
453
|
+
> I'm used to defining my routes in a single file, why should I change?
|
|
454
|
+
|
|
455
|
+
Something you'll notice (quite soon) in the TanStack Router documentation is that we push for **file-based routing** as the preferred method for defining your routes. This is because we've found that file-based routing is the most scalable and maintainable way to define your routes.
|
|
456
|
+
|
|
457
|
+
> [!TIP]
|
|
458
|
+
> Before you continue, it's important you have a good understanding of [code-based routing](../routing/code-based-routing.md) and [file-based routing](../routing/file-based-routing.md).
|
|
459
|
+
|
|
460
|
+
As mentioned in the beginning, TanStack Router was designed for complex applications that require a high degree of type-safety and maintainability. And to achieve this, the configuration of the router has been done in a precise way that allows TypeScript to infer the types of your routes as much as possible.
|
|
461
|
+
|
|
462
|
+
A key difference in the set-up of a _basic_ application with TanStack Router, is that your route configurations require a function to be provided to \`getParentRoute\`, that returns the parent route of the current route.
|
|
331
463
|
|
|
332
464
|
\`\`\`tsx
|
|
333
|
-
import {
|
|
334
|
-
import
|
|
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'
|
|
465
|
+
import { createRoute } from '@tanstack/react-router'
|
|
466
|
+
import { postsRoute } from './postsRoute'
|
|
344
467
|
|
|
345
|
-
const
|
|
346
|
-
|
|
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
|
-
),
|
|
468
|
+
export const postsIndexRoute = createRoute({
|
|
469
|
+
getParentRoute: () => postsRoute,
|
|
470
|
+
path: '/',
|
|
361
471
|
})
|
|
472
|
+
\`\`\`
|
|
473
|
+
|
|
474
|
+
At this stage, this is done so the definition of \`postsIndexRoute\` can be aware of its location in the route tree and so that it can correctly infer the types of the \`context\`, \`path params\`, \`search params\` returned by the parent route. Incorrectly defining the \`getParentRoute\` function means that the properties of the parent route will not be correctly inferred by the child route.
|
|
475
|
+
|
|
476
|
+
As such, this is a critical part of the route configuration and a point of failure if not done correctly.
|
|
362
477
|
|
|
363
|
-
|
|
364
|
-
|
|
478
|
+
But this is only one part of setting up a basic application. TanStack Router requires all the routes (including the root route) to be stitched into a **_route-tree_** so that it may be passed into the \`createRouter\` function before declaring the \`Router\` instance on the module for type inference. This is another critical part of the route configuration and a point of failure if not done correctly.
|
|
479
|
+
|
|
480
|
+
> 🤯 If this route-tree were in its own file for an application with ~40-50 routes, it can easily grow up to 700+ lines.
|
|
481
|
+
|
|
482
|
+
\`\`\`tsx
|
|
483
|
+
const routeTree = rootRoute.addChildren([
|
|
484
|
+
postsRoute.addChildren([postsIndexRoute, postsIdRoute]),
|
|
485
|
+
])
|
|
486
|
+
\`\`\`
|
|
487
|
+
|
|
488
|
+
This complexity only increases as you begin to use more features of the router, such as nested context, loaders, search param validation, etc. As such, it no longer becomes feasible to define your routes in a single file. And so, users end up building their own _semi consistent_ way of defining their routes across multiple files. This can lead to inconsistencies and errors in the route configuration.
|
|
489
|
+
|
|
490
|
+
Finally, comes the issue of code-splitting. As your application grows, you'll want to code-split your components to reduce the initial bundle size of your application. This can be a bit of a headache to manage when you're defining your routes in a single file or even across multiple files.
|
|
491
|
+
|
|
492
|
+
\`\`\`tsx
|
|
493
|
+
import { createRoute, lazyRouteComponent } from '@tanstack/react-router'
|
|
494
|
+
import { postsRoute } from './postsRoute'
|
|
495
|
+
|
|
496
|
+
export const postsIndexRoute = createRoute({
|
|
497
|
+
getParentRoute: () => postsRoute,
|
|
365
498
|
path: '/',
|
|
366
|
-
component:
|
|
367
|
-
return (
|
|
368
|
-
<div className="p-2">
|
|
369
|
-
<h3>Welcome Home!</h3>
|
|
370
|
-
</div>
|
|
371
|
-
)
|
|
372
|
-
},
|
|
499
|
+
component: lazyRouteComponent(() => import('../page-components/posts/index')),
|
|
373
500
|
})
|
|
501
|
+
\`\`\`
|
|
374
502
|
|
|
375
|
-
|
|
376
|
-
getParentRoute: () => rootRoute,
|
|
377
|
-
path: '/about',
|
|
378
|
-
component: function About() {
|
|
379
|
-
return <div className="p-2">Hello from About!</div>
|
|
380
|
-
},
|
|
381
|
-
})
|
|
503
|
+
All of this boilerplate, no matter how essential for providing a best-in-class type-inference experience, can be a bit overwhelming and can lead to inconsistencies and errors in the route configuration.
|
|
382
504
|
|
|
383
|
-
|
|
505
|
+
... and this example configuration is just for rendering a single codes-split route. Imagine having to do this for 40-50 routes. Now remember that you still haven't touched the \`context\`, \`loaders\`, \`search param validation\`, and other features of the router 🤕.
|
|
384
506
|
|
|
385
|
-
|
|
507
|
+
> So, why's file-based routing the preferred way?
|
|
386
508
|
|
|
387
|
-
|
|
388
|
-
interface Register {
|
|
389
|
-
router: typeof router
|
|
390
|
-
}
|
|
391
|
-
}
|
|
509
|
+
TanStack Router's file-based routing is designed to solve all of these issues. It allows you to define your routes in a predictable way that is easy to manage and maintain, and is scalable as your application grows.
|
|
392
510
|
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
511
|
+
The file-based routing approach is powered by the TanStack Router Bundler Plugin. It performs 3 essential tasks that solve the pain points in route configuration when using code-based routing:
|
|
512
|
+
|
|
513
|
+
1. **Route configuration boilerplate**: It generates the boilerplate for your route configurations.
|
|
514
|
+
2. **Route tree stitching**: It stitches together your route configurations into a single cohesive route-tree. Also in the background, it correctly updates the route configurations to define the \`getParentRoute\` function match the routes with their parent routes.
|
|
515
|
+
3. **Code-splitting**: It automatically code-splits your route content components and updates the route configurations with the correct component. Additionally, at runtime, it ensures that the correct component is loaded when the route is visited.
|
|
516
|
+
|
|
517
|
+
Let's take a look at how the route configuration for the previous example would look like with file-based routing.
|
|
518
|
+
|
|
519
|
+
\`\`\`tsx
|
|
520
|
+
// src/routes/posts/index.ts
|
|
521
|
+
import { createFileRoute } from '@tanstack/react-router'
|
|
522
|
+
|
|
523
|
+
export const Route = createFileRoute('/posts/')({
|
|
524
|
+
component: () => 'Posts index component goes here!!!',
|
|
525
|
+
})
|
|
402
526
|
\`\`\`
|
|
403
527
|
|
|
404
|
-
|
|
528
|
+
That's it! No need to worry about defining the \`getParentRoute\` function, stitching together the route-tree, or code-splitting your components. The TanStack Router Bundler Plugin handles all of this for you.
|
|
529
|
+
|
|
530
|
+
At no point does the TanStack Router Bundler Plugin take away your control over your route configurations. It's designed to be as flexible as possible, allowing you to define your routes in a way that suits your application whilst reducing the boilerplate and complexity of the route configuration.
|
|
531
|
+
|
|
532
|
+
Check out the guides for [file-based routing](../routing/file-based-routing.md) and [code-splitting](../guide/code-splitting.md) for a more in-depth explanation of how they work in TanStack Router.
|
|
405
533
|
|
|
406
534
|
# Devtools
|
|
407
535
|
|
|
@@ -593,307 +721,23 @@ function App() {
|
|
|
593
721
|
- Specifies a Shadow DOM target for the devtools.
|
|
594
722
|
- 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
723
|
|
|
596
|
-
#
|
|
597
|
-
|
|
598
|
-
**_If your UI is blank, open the console, and you will probably have some errors that read something along the lines of \`cannot use 'useNavigate' outside of context\` . This means there are React Router api’s that are still imported and referenced that you need to find and remove. The easiest way to make sure you find all React Router imports is to uninstall \`react-router-dom\` and then you should get typescript errors in your files. Then you will know what to change to a \`@tanstack/react-router\` import._**
|
|
599
|
-
|
|
600
|
-
Here is the [example repo](https://github.com/Benanna2019/SickFitsForEveryone/tree/migrate-to-tanstack/router/React-Router)
|
|
601
|
-
|
|
602
|
-
- [ ] Install Router - \`npm i @tanstack/react-router\` (see [detailed installation guide](../how-to/install.md))
|
|
603
|
-
- [ ] **Optional:** Uninstall React Router to get TypeScript errors on imports.
|
|
604
|
-
- At this point I don’t know if you can do a gradual migration, but it seems likely you could have multiple router providers, not desirable.
|
|
605
|
-
- The api’s between React Router and TanStack Router are very similar and could most likely be handled in a sprint cycle or two if that is your companies way of doing things.
|
|
606
|
-
- [ ] Create Routes for each existing React Router route we have
|
|
607
|
-
- [ ] Create root route
|
|
608
|
-
- [ ] Create router instance
|
|
609
|
-
- [ ] Add global module in main.tsx
|
|
610
|
-
- [ ] Remove any React Router (\`createBrowserRouter\` or \`BrowserRouter\`), \`Routes\`, and \`Route\` Components from main.tsx
|
|
611
|
-
- [ ] **Optional:** Refactor \`render\` function for custom setup/providers - The repo referenced above has an example - This was necessary in the case of Supertokens. Supertoken has a specific setup with React Router and a different setup with all other React implementations
|
|
612
|
-
- [ ] Set RouterProvider and pass it the router as the prop
|
|
613
|
-
- [ ] Replace all instances of React Router \`Link\` component with \`@tanstack/react-router\` \`Link\` component
|
|
614
|
-
- [ ] Add \`to\` prop with literal path
|
|
615
|
-
- [ ] Add \`params\` prop, where necessary with params like so \`params={{ orderId: order.id }}\`
|
|
616
|
-
- [ ] Replace all instances of React Router \`useNavigate\` hook with \`@tanstack/react-router\` \`useNavigate\` hook
|
|
617
|
-
- [ ] Set \`to\` property and \`params\` property where needed
|
|
618
|
-
- [ ] Replace any React Router \`Outlet\`'s with the \`@tanstack/react-router\` equivalent
|
|
619
|
-
- [ ] If you are using \`useSearchParams\` hook from React Router, move the search params default value to the validateSearch property on a Route definition.
|
|
620
|
-
- [ ] Instead of using the \`useSearchParams\` hook, use \`@tanstack/react-router\` \`Link\`'s search property to update the search params state
|
|
621
|
-
- [ ] To read search params you can do something like the following
|
|
622
|
-
- \`const { page } = useSearch({ from: productPage.fullPath })\`
|
|
623
|
-
- [ ] If using React Router’s \`useParams\` hook, update the import to be from \`@tanstack/react-router\` and set the \`from\` property to the literal path name where you want to read the params object from
|
|
624
|
-
- So say we have a route with the path name \`orders/$orderid\`.
|
|
625
|
-
- In the \`useParams\` hook we would set up our hook like so: \`const params = useParams({ from: "/orders/$orderId" })\`
|
|
626
|
-
- Then wherever we wanted to access the order id we would get it off of the params object \`params.orderId\`
|
|
627
|
-
|
|
628
|
-
# Migration from React Location
|
|
629
|
-
|
|
630
|
-
Before you begin your journey in migrating from React Location, it's important that you have a good understanding of the [Routing Concepts](../routing/routing-concepts.md) and [Design Decisions](../decisions-on-dx.md) used by TanStack Router.
|
|
631
|
-
|
|
632
|
-
## Differences between React Location and TanStack Router
|
|
633
|
-
|
|
634
|
-
React Location and TanStack Router share much of same design decisions concepts, but there are some key differences that you should be aware of.
|
|
635
|
-
|
|
636
|
-
- React Location uses _generics_ to infer types for routes, while TanStack Router uses _module declaration merging_ to infer types.
|
|
637
|
-
- Route configuration in React Location is done using a single array of route definitions, while in TanStack Router, route configuration is done using a tree of route definitions starting with the [root route](../routing/routing-concepts.md#the-root-route).
|
|
638
|
-
- [File-based routing](../routing/file-based-routing.md) is the recommended way to define routes in TanStack Router, while React Location only allows you to define routes in a single file using a code-based approach.
|
|
639
|
-
- TanStack Router does support a [code-based approach](../routing/code-based-routing.md) to defining routes, but it is not recommended for most use cases. You can read more about why, over here: [why is file-based routing the preferred way to define routes?](../decisions-on-dx.md#3-why-is-file-based-routing-the-preferred-way-to-define-routes)
|
|
640
|
-
|
|
641
|
-
## Migration guide
|
|
642
|
-
|
|
643
|
-
In this guide we'll go over the process of migrating the [React Location Basic example](https://github.com/TanStack/router/tree/react-location/examples/basic) over to TanStack Router using file-based routing, with the end goal of having the same functionality as the original example (styling and other non-routing related code will be omitted).
|
|
644
|
-
|
|
645
|
-
> [!TIP]
|
|
646
|
-
> To use a code-based approach for defining your routes, you can read the [code-based Routing](../routing/code-based-routing.md) guide.
|
|
647
|
-
|
|
648
|
-
### Step 1: Swap over to TanStack Router's dependencies
|
|
649
|
-
|
|
650
|
-
First, we need to install the dependencies for TanStack Router. For detailed installation instructions, see our [How to Install TanStack Router](../how-to/install.md) guide.
|
|
651
|
-
|
|
652
|
-
\`\`\`sh
|
|
653
|
-
npm install @tanstack/react-router @tanstack/router-devtools
|
|
654
|
-
\`\`\`
|
|
655
|
-
|
|
656
|
-
And remove the React Location dependencies.
|
|
657
|
-
|
|
658
|
-
\`\`\`sh
|
|
659
|
-
npm uninstall @tanstack/react-location @tanstack/react-location-devtools
|
|
660
|
-
\`\`\`
|
|
661
|
-
|
|
662
|
-
### Step 2: Use the file-based routing watcher
|
|
663
|
-
|
|
664
|
-
If your project uses Vite (or one of the supported bundlers), you can use the TanStack Router plugin to watch for changes in your routes files and automatically update the routes configuration.
|
|
665
|
-
|
|
666
|
-
Installation of the Vite plugin:
|
|
667
|
-
|
|
668
|
-
\`\`\`sh
|
|
669
|
-
npm install -D @tanstack/router-plugin
|
|
670
|
-
\`\`\`
|
|
671
|
-
|
|
672
|
-
And add it to your \`vite.config.js\`:
|
|
673
|
-
|
|
674
|
-
\`\`\`js
|
|
675
|
-
import { defineConfig } from 'vite'
|
|
676
|
-
import react from '@vitejs/plugin-react'
|
|
677
|
-
import { tanstackRouter } from '@tanstack/router-plugin/vite'
|
|
678
|
-
|
|
679
|
-
export default defineConfig({
|
|
680
|
-
// ...
|
|
681
|
-
plugins: [tanstackRouter(), react()],
|
|
682
|
-
})
|
|
683
|
-
\`\`\`
|
|
684
|
-
|
|
685
|
-
However, if your application does not use Vite, you use one of our other [supported bundlers](../routing/file-based-routing.md#getting-started-with-file-based-routing), or you can use the \`@tanstack/router-cli\` package to watch for changes in your routes files and automatically update the routes configuration.
|
|
686
|
-
|
|
687
|
-
### Step 3: Add the file-based configuration file to your project
|
|
688
|
-
|
|
689
|
-
Create a \`tsr.config.json\` file in the root of your project with the following content:
|
|
690
|
-
|
|
691
|
-
\`\`\`json
|
|
692
|
-
{
|
|
693
|
-
"routesDirectory": "./src/routes",
|
|
694
|
-
"generatedRouteTree": "./src/routeTree.gen.ts"
|
|
695
|
-
}
|
|
696
|
-
\`\`\`
|
|
697
|
-
|
|
698
|
-
You can find the full list of options for the \`tsr.config.json\` file [here](../../../api/file-based-routing.md).
|
|
699
|
-
|
|
700
|
-
### Step 4: Create the routes directory
|
|
701
|
-
|
|
702
|
-
Create a \`routes\` directory in the \`src\` directory of your project.
|
|
703
|
-
|
|
704
|
-
\`\`\`sh
|
|
705
|
-
mkdir src/routes
|
|
706
|
-
\`\`\`
|
|
707
|
-
|
|
708
|
-
### Step 5: Create the root route file
|
|
709
|
-
|
|
710
|
-
\`\`\`tsx
|
|
711
|
-
// src/routes/__root.tsx
|
|
712
|
-
import { createRootRoute, Outlet, Link } from '@tanstack/react-router'
|
|
713
|
-
import { TanStackRouterDevtools } from '@tanstack/router-devtools'
|
|
714
|
-
|
|
715
|
-
export const Route = createRootRoute({
|
|
716
|
-
component: () => {
|
|
717
|
-
return (
|
|
718
|
-
<>
|
|
719
|
-
<div>
|
|
720
|
-
<Link to="/" activeOptions={{ exact: true }}>
|
|
721
|
-
Home
|
|
722
|
-
</Link>
|
|
723
|
-
<Link to="/posts">Posts</Link>
|
|
724
|
-
</div>
|
|
725
|
-
<hr />
|
|
726
|
-
<Outlet />
|
|
727
|
-
<TanStackRouterDevtools />
|
|
728
|
-
</>
|
|
729
|
-
)
|
|
730
|
-
},
|
|
731
|
-
})
|
|
732
|
-
\`\`\`
|
|
733
|
-
|
|
734
|
-
### Step 6: Create the index route file
|
|
735
|
-
|
|
736
|
-
\`\`\`tsx
|
|
737
|
-
// src/routes/index.tsx
|
|
738
|
-
import { createFileRoute } from '@tanstack/react-router'
|
|
739
|
-
|
|
740
|
-
export const Route = createFileRoute('/')({
|
|
741
|
-
component: Index,
|
|
742
|
-
})
|
|
743
|
-
\`\`\`
|
|
744
|
-
|
|
745
|
-
> You will need to move any related components and logic needed for the index route from the \`src/index.tsx\` file to the \`src/routes/index.tsx\` file.
|
|
746
|
-
|
|
747
|
-
### Step 7: Create the posts route file
|
|
748
|
-
|
|
749
|
-
\`\`\`tsx
|
|
750
|
-
// src/routes/posts.tsx
|
|
751
|
-
import { createFileRoute, Link, Outlet } from '@tanstack/react-router'
|
|
752
|
-
|
|
753
|
-
export const Route = createFileRoute('/posts')({
|
|
754
|
-
component: Posts,
|
|
755
|
-
loader: async () => {
|
|
756
|
-
const posts = await fetchPosts()
|
|
757
|
-
return {
|
|
758
|
-
posts,
|
|
759
|
-
}
|
|
760
|
-
},
|
|
761
|
-
})
|
|
762
|
-
|
|
763
|
-
function Posts() {
|
|
764
|
-
const { posts } = Route.useLoaderData()
|
|
765
|
-
return (
|
|
766
|
-
<div>
|
|
767
|
-
<nav>
|
|
768
|
-
{posts.map((post) => (
|
|
769
|
-
<Link
|
|
770
|
-
key={post.id}
|
|
771
|
-
to={\`/posts/$postId\`}
|
|
772
|
-
params={{ postId: post.id }}
|
|
773
|
-
>
|
|
774
|
-
{post.title}
|
|
775
|
-
</Link>
|
|
776
|
-
))}
|
|
777
|
-
</nav>
|
|
778
|
-
<Outlet />
|
|
779
|
-
</div>
|
|
780
|
-
)
|
|
781
|
-
}
|
|
782
|
-
\`\`\`
|
|
783
|
-
|
|
784
|
-
> You will need to move any related components and logic needed for the posts route from the \`src/index.tsx\` file to the \`src/routes/posts.tsx\` file.
|
|
785
|
-
|
|
786
|
-
### Step 8: Create the posts index route file
|
|
787
|
-
|
|
788
|
-
\`\`\`tsx
|
|
789
|
-
// src/routes/posts.index.tsx
|
|
790
|
-
import { createFileRoute } from '@tanstack/react-router'
|
|
791
|
-
|
|
792
|
-
export const Route = createFileRoute('/posts/')({
|
|
793
|
-
component: PostsIndex,
|
|
794
|
-
})
|
|
795
|
-
\`\`\`
|
|
796
|
-
|
|
797
|
-
> You will need to move any related components and logic needed for the posts index route from the \`src/index.tsx\` file to the \`src/routes/posts.index.tsx\` file.
|
|
798
|
-
|
|
799
|
-
### Step 9: Create the posts id route file
|
|
800
|
-
|
|
801
|
-
\`\`\`tsx
|
|
802
|
-
// src/routes/posts.$postId.tsx
|
|
803
|
-
import { createFileRoute } from '@tanstack/react-router'
|
|
804
|
-
|
|
805
|
-
export const Route = createFileRoute('/posts/$postId')({
|
|
806
|
-
component: PostsId,
|
|
807
|
-
loader: async ({ params: { postId } }) => {
|
|
808
|
-
const post = await fetchPost(postId)
|
|
809
|
-
return {
|
|
810
|
-
post,
|
|
811
|
-
}
|
|
812
|
-
},
|
|
813
|
-
})
|
|
814
|
-
|
|
815
|
-
function PostsId() {
|
|
816
|
-
const { post } = Route.useLoaderData()
|
|
817
|
-
// ...
|
|
818
|
-
}
|
|
819
|
-
\`\`\`
|
|
820
|
-
|
|
821
|
-
> You will need to move any related components and logic needed for the posts id route from the \`src/index.tsx\` file to the \`src/routes/posts.$postId.tsx\` file.
|
|
822
|
-
|
|
823
|
-
### Step 10: Generate the route tree
|
|
824
|
-
|
|
825
|
-
If you are using one of the supported bundlers, the route tree will be generated automatically when you run the dev script.
|
|
826
|
-
|
|
827
|
-
If you are not using one of the supported bundlers, you can generate the route tree by running the following command:
|
|
828
|
-
|
|
829
|
-
\`\`\`sh
|
|
830
|
-
npx tsr generate
|
|
831
|
-
\`\`\`
|
|
832
|
-
|
|
833
|
-
### Step 11: Update the main entry file to render the Router
|
|
834
|
-
|
|
835
|
-
Once you've generated the route-tree, you can then update the \`src/index.tsx\` file to create the router instance and render it.
|
|
836
|
-
|
|
837
|
-
\`\`\`tsx
|
|
838
|
-
// src/index.tsx
|
|
839
|
-
import React from 'react'
|
|
840
|
-
import ReactDOM from 'react-dom'
|
|
841
|
-
import { createRouter, RouterProvider } from '@tanstack/react-router'
|
|
842
|
-
|
|
843
|
-
// Import the generated route tree
|
|
844
|
-
import { routeTree } from './routeTree.gen'
|
|
845
|
-
|
|
846
|
-
// Create a new router instance
|
|
847
|
-
const router = createRouter({ routeTree })
|
|
848
|
-
|
|
849
|
-
// Register the router instance for type safety
|
|
850
|
-
declare module '@tanstack/react-router' {
|
|
851
|
-
interface Register {
|
|
852
|
-
router: typeof router
|
|
853
|
-
}
|
|
854
|
-
}
|
|
855
|
-
|
|
856
|
-
const domElementId = 'root' // Assuming you have a root element with the id 'root'
|
|
857
|
-
|
|
858
|
-
// Render the app
|
|
859
|
-
const rootElement = document.getElementById(domElementId)
|
|
860
|
-
if (!rootElement) {
|
|
861
|
-
throw new Error(\`Element with id \${domElementId} not found\`)
|
|
862
|
-
}
|
|
863
|
-
|
|
864
|
-
ReactDOM.createRoot(rootElement).render(
|
|
865
|
-
<React.StrictMode>
|
|
866
|
-
<RouterProvider router={router} />
|
|
867
|
-
</React.StrictMode>,
|
|
868
|
-
)
|
|
869
|
-
\`\`\`
|
|
870
|
-
|
|
871
|
-
### Finished!
|
|
872
|
-
|
|
873
|
-
You should now have successfully migrated your application from React Location to TanStack Router using file-based routing.
|
|
724
|
+
# Frequently Asked Questions
|
|
874
725
|
|
|
875
|
-
|
|
726
|
+
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).
|
|
876
727
|
|
|
877
|
-
|
|
878
|
-
- [Data loading](../guide/data-loading.md)
|
|
879
|
-
- [History types](../guide/history-types.md)
|
|
880
|
-
- [Wildcard / Splat / Catch-all routes](../routing/routing-concepts.md#splat--catch-all-routes)
|
|
881
|
-
- [Authenticated routes](../guide/authenticated-routes.md)
|
|
728
|
+
## Why should you choose TanStack Router over another router?
|
|
882
729
|
|
|
883
|
-
|
|
730
|
+
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:
|
|
884
731
|
|
|
885
|
-
-
|
|
886
|
-
-
|
|
887
|
-
- [Pathless Layout Routes](../routing/routing-concepts.md#pathless-layout-routes)
|
|
888
|
-
- [Route masking](../guide/route-masking.md)
|
|
889
|
-
- [SSR](../guide/ssr.md)
|
|
890
|
-
- ... and more!
|
|
732
|
+
- **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.
|
|
733
|
+
- **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.
|
|
891
734
|
|
|
892
|
-
|
|
735
|
+
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.
|
|
893
736
|
|
|
894
|
-
|
|
737
|
+
## Is TanStack Router a framework?
|
|
895
738
|
|
|
896
|
-
|
|
739
|
+
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.
|
|
740
|
+
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).
|
|
897
741
|
|
|
898
742
|
## Should I commit my \`routeTree.gen.ts\` file into git?
|
|
899
743
|
|