@tanstack/react-router 1.139.0 → 1.139.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.
@@ -3829,7 +3829,7 @@ export const Route = createFileRoute('/posts/$postId')({
3829
3829
 
3830
3830
  The not-found error above will be handled by the same route or nearest parent route that has either a \`notFoundComponent\` route option or the \`defaultNotFoundComponent\` router option configured.
3831
3831
 
3832
- If neither the route nor any suitable parent route is found to handle the error, the root route will handle it using TanStack Router's **extremely basic (and purposefully undesirable)** default not-found component that simply renders \`<div>Not Found</div>\`. It's highly recommended to either attach at least one \`notFoundComponent\` to the root route or configure a router-wide \`defaultNotFoundComponent\` to handle not-found errors.
3832
+ If neither the route nor any suitable parent route is found to handle the error, the root route will handle it using TanStack Router's **extremely basic (and purposefully undesirable)** default not-found component that simply renders \`<p>Not Found</p>\`. It's highly recommended to either attach at least one \`notFoundComponent\` to the root route or configure a router-wide \`defaultNotFoundComponent\` to handle not-found errors.
3833
3833
 
3834
3834
  > ⚠️ Throwing a notFound error in a beforeLoad method will always trigger the \_\_root notFoundComponent. Since beforeLoad methods are run prior to the route loader methods, there is no guarantee that any required data for layouts have successfully loaded before the error is thrown.
3835
3835
 
@@ -1,2 +1,2 @@
1
- declare const _default: "# Code-Based Routing\n\n> [!TIP]\n> Code-based routing is not recommended for most applications. It is recommended to use [File-Based Routing](../file-based-routing.md) instead.\n\n## \u26A0\uFE0F Before You Start\n\n- If you're using [File-Based Routing](../file-based-routing.md), **skip this guide**.\n- If you still insist on using code-based routing, you must read the [Routing Concepts](../routing-concepts.md) guide first, as it also covers core concepts of the router.\n\n## Route Trees\n\nCode-based routing is no different from file-based routing in that it uses the same route tree concept to organize, match and compose matching routes into a component tree. The only difference is that instead of using the filesystem to organize your routes, you use code.\n\nLet's consider the same route tree from the [Route Trees & Nesting](../route-trees.md#route-trees) guide, and convert it to code-based routing:\n\nHere is the file-based version:\n\n```\nroutes/\n\u251C\u2500\u2500 __root.tsx\n\u251C\u2500\u2500 index.tsx\n\u251C\u2500\u2500 about.tsx\n\u251C\u2500\u2500 posts/\n\u2502 \u251C\u2500\u2500 index.tsx\n\u2502 \u251C\u2500\u2500 $postId.tsx\n\u251C\u2500\u2500 posts.$postId.edit.tsx\n\u251C\u2500\u2500 settings/\n\u2502 \u251C\u2500\u2500 profile.tsx\n\u2502 \u251C\u2500\u2500 notifications.tsx\n\u251C\u2500\u2500 _pathlessLayout.tsx\n\u251C\u2500\u2500 _pathlessLayout/\n\u2502 \u251C\u2500\u2500 route-a.tsx\n\u251C\u2500\u2500 \u251C\u2500\u2500 route-b.tsx\n\u251C\u2500\u2500 files/\n\u2502 \u251C\u2500\u2500 $.tsx\n```\n\nAnd here is a summarized code-based version:\n\n```tsx\nimport { createRootRoute, createRoute } from '@tanstack/react-router'\n\nconst rootRoute = createRootRoute()\n\nconst indexRoute = createRoute({\n getParentRoute: () => rootRoute,\n path: '/',\n})\n\nconst aboutRoute = createRoute({\n getParentRoute: () => rootRoute,\n path: 'about',\n})\n\nconst postsRoute = createRoute({\n getParentRoute: () => rootRoute,\n path: 'posts',\n})\n\nconst postsIndexRoute = createRoute({\n getParentRoute: () => postsRoute,\n path: '/',\n})\n\nconst postRoute = createRoute({\n getParentRoute: () => postsRoute,\n path: '$postId',\n})\n\nconst postEditorRoute = createRoute({\n getParentRoute: () => rootRoute,\n path: 'posts/$postId/edit',\n})\n\nconst settingsRoute = createRoute({\n getParentRoute: () => rootRoute,\n path: 'settings',\n})\n\nconst profileRoute = createRoute({\n getParentRoute: () => settingsRoute,\n path: 'profile',\n})\n\nconst notificationsRoute = createRoute({\n getParentRoute: () => settingsRoute,\n path: 'notifications',\n})\n\nconst pathlessLayoutRoute = createRoute({\n getParentRoute: () => rootRoute,\n id: 'pathlessLayout',\n})\n\nconst pathlessLayoutARoute = createRoute({\n getParentRoute: () => pathlessLayoutRoute,\n path: 'route-a',\n})\n\nconst pathlessLayoutBRoute = createRoute({\n getParentRoute: () => pathlessLayoutRoute,\n path: 'route-b',\n})\n\nconst filesRoute = createRoute({\n getParentRoute: () => rootRoute,\n path: 'files/$',\n})\n```\n\n## Anatomy of a Route\n\nAll other routes other than the root route are configured using the `createRoute` function:\n\n```tsx\nconst route = createRoute({\n getParentRoute: () => rootRoute,\n path: '/posts',\n component: PostsComponent,\n})\n```\n\nThe `getParentRoute` option is a function that returns the parent route of the route you're creating.\n\n**\u2753\u2753\u2753 \"Wait, you're making me pass the parent route for every route I make?\"**\n\nAbsolutely! The reason for passing the parent route has **everything to do with the magical type safety** of TanStack Router. Without the parent route, TypeScript would have no idea what types to supply your route with!\n\n> [!IMPORTANT]\n> For every route that's **NOT** the **Root Route** or a **Pathless Layout Route**, a `path` option is required. This is the path that will be matched against the URL pathname to determine if the route is a match.\n\nWhen configuring route `path` option on a route, it ignores leading and trailing slashes (this does not include \"index\" route paths `/`). You can include them if you want, but they will be normalized internally by TanStack Router. Here is a table of valid paths and what they will be normalized to:\n\n| Path | Normalized Path |\n| -------- | --------------- |\n| `/` | `/` |\n| `/about` | `about` |\n| `about/` | `about` |\n| `about` | `about` |\n| `$` | `$` |\n| `/$` | `$` |\n| `/$/` | `$` |\n\n## Manually building the route tree\n\nWhen building a route tree in code, it's not enough to define the parent route of each route. You must also construct the final route tree by adding each route to its parent route's `children` array. This is because the route tree is not built automatically for you like it is in file-based routing.\n\n```tsx\n/* prettier-ignore */\nconst routeTree = rootRoute.addChildren([\n indexRoute,\n aboutRoute,\n postsRoute.addChildren([\n postsIndexRoute,\n postRoute,\n ]),\n postEditorRoute,\n settingsRoute.addChildren([\n profileRoute,\n notificationsRoute,\n ]),\n pathlessLayoutRoute.addChildren([\n pathlessLayoutARoute,\n pathlessLayoutBRoute,\n ]),\n filesRoute.addChildren([\n fileRoute,\n ]),\n])\n/* prettier-ignore-end */\n```\n\nBut before you can go ahead and build the route tree, you need to understand how the Routing Concepts for Code-Based Routing work.\n\n## Routing Concepts for Code-Based Routing\n\nBelieve it or not, file-based routing is really a superset of code-based routing and uses the filesystem and a bit of code-generation abstraction on top of it to generate this structure you see above automatically.\n\nWe're going to assume you've read the [Routing Concepts](../routing-concepts.md) guide and are familiar with each of these main concepts:\n\n- The Root Route\n- Basic Routes\n- Index Routes\n- Dynamic Route Segments\n- Splat / Catch-All Routes\n- Layout Routes\n- Pathless Routes\n- Non-Nested Routes\n\nNow, let's take a look at how to create each of these route types in code.\n\n## The Root Route\n\nCreating a root route in code-based routing is thankfully the same as doing so in file-based routing. Call the `createRootRoute()` function.\n\nUnlike file-based routing however, you do not need to export the root route if you don't want to. It's certainly not recommended to build an entire route tree and application in a single file (although you can and we do this in the examples to demonstrate routing concepts in brevity).\n\n```tsx\n// Standard root route\nimport { createRootRoute } from '@tanstack/react-router'\n\nconst rootRoute = createRootRoute()\n\n// Root route with Context\nimport { createRootRouteWithContext } from '@tanstack/react-router'\nimport type { QueryClient } from '@tanstack/react-query'\n\nexport interface MyRouterContext {\n queryClient: QueryClient\n}\nconst rootRoute = createRootRouteWithContext<MyRouterContext>()\n```\n\nTo learn more about Context in TanStack Router, see the [Router Context](../../guide/router-context.md) guide.\n\n## Basic Routes\n\nTo create a basic route, simply provide a normal `path` string to the `createRoute` function:\n\n```tsx\nconst aboutRoute = createRoute({\n getParentRoute: () => rootRoute,\n path: 'about',\n})\n```\n\nSee, it's that simple! The `aboutRoute` will match the URL `/about`.\n\n## Index Routes\n\nUnlike file-based routing, which uses the `index` filename to denote an index route, code-based routing uses a single slash `/` to denote an index route. For example, the `posts.index.tsx` file from our example route tree above would be represented in code-based routing like this:\n\n```tsx\nconst postsRoute = createRoute({\n getParentRoute: () => rootRoute,\n path: 'posts',\n})\n\nconst postsIndexRoute = createRoute({\n getParentRoute: () => postsRoute,\n // Notice the single slash `/` here\n path: '/',\n})\n```\n\nSo, the `postsIndexRoute` will match the URL `/posts/` (or `/posts`).\n\n## Dynamic Route Segments\n\nDynamic route segments work exactly the same in code-based routing as they do in file-based routing. Simply prefix a segment of the path with a `$` and it will be captured into the `params` object of the route's `loader` or `component`:\n\n```tsx\nconst postIdRoute = createRoute({\n getParentRoute: () => postsRoute,\n path: '$postId',\n // In a loader\n loader: ({ params }) => fetchPost(params.postId),\n // Or in a component\n component: PostComponent,\n})\n\nfunction PostComponent() {\n const { postId } = postIdRoute.useParams()\n return <div>Post ID: {postId}</div>\n}\n```\n\n> [!TIP]\n> If your component is code-split, you can use the [getRouteApi function](../../guide/code-splitting.md#manually-accessing-route-apis-in-other-files-with-the-getrouteapi-helper) to avoid having to import the `postIdRoute` configuration to get access to the typed `useParams()` hook.\n\n## Splat / Catch-All Routes\n\nAs expected, splat/catch-all routes also work the same in code-based routing as they do in file-based routing. Simply prefix a segment of the path with a `$` and it will be captured into the `params` object under the `_splat` key:\n\n```tsx\nconst filesRoute = createRoute({\n getParentRoute: () => rootRoute,\n path: 'files',\n})\n\nconst fileRoute = createRoute({\n getParentRoute: () => filesRoute,\n path: '$',\n})\n```\n\nFor the URL `/documents/hello-world`, the `params` object will look like this:\n\n```js\n{\n '_splat': 'documents/hello-world'\n}\n```\n\n## Layout Routes\n\nLayout routes are routes that wrap their children in a layout component. In code-based routing, you can create a layout route by simply nesting a route under another route:\n\n```tsx\nconst postsRoute = createRoute({\n getParentRoute: () => rootRoute,\n path: 'posts',\n component: PostsLayoutComponent, // The layout component\n})\n\nfunction PostsLayoutComponent() {\n return (\n <div>\n <h1>Posts</h1>\n <Outlet />\n </div>\n )\n}\n\nconst postsIndexRoute = createRoute({\n getParentRoute: () => postsRoute,\n path: '/',\n})\n\nconst postsCreateRoute = createRoute({\n getParentRoute: () => postsRoute,\n path: 'create',\n})\n\nconst routeTree = rootRoute.addChildren([\n // The postsRoute is the layout route\n // Its children will be nested under the PostsLayoutComponent\n postsRoute.addChildren([postsIndexRoute, postsCreateRoute]),\n])\n```\n\nNow, both the `postsIndexRoute` and `postsCreateRoute` will render their contents inside of the `PostsLayoutComponent`:\n\n```tsx\n// URL: /posts\n<PostsLayoutComponent>\n <PostsIndexComponent />\n</PostsLayoutComponent>\n\n// URL: /posts/create\n<PostsLayoutComponent>\n <PostsCreateComponent />\n</PostsLayoutComponent>\n```\n\n## Pathless Layout Routes\n\nIn file-based routing a pathless layout route is prefixed with a `_`, but in code-based routing, this is simply a route with an `id` instead of a `path` option. This is because code-based routing does not use the filesystem to organize routes, so there is no need to prefix a route with a `_` to denote that it has no path.\n\n```tsx\nconst pathlessLayoutRoute = createRoute({\n getParentRoute: () => rootRoute,\n id: 'pathlessLayout',\n component: PathlessLayoutComponent,\n})\n\nfunction PathlessLayoutComponent() {\n return (\n <div>\n <h1>Pathless Layout</h1>\n <Outlet />\n </div>\n )\n}\n\nconst pathlessLayoutARoute = createRoute({\n getParentRoute: () => pathlessLayoutRoute,\n path: 'route-a',\n})\n\nconst pathlessLayoutBRoute = createRoute({\n getParentRoute: () => pathlessLayoutRoute,\n path: 'route-b',\n})\n\nconst routeTree = rootRoute.addChildren([\n // The pathless layout route has no path, only an id\n // So its children will be nested under the pathless layout route\n pathlessLayoutRoute.addChildren([pathlessLayoutARoute, pathlessLayoutBRoute]),\n])\n```\n\nNow both `/route-a` and `/route-b` will render their contents inside of the `PathlessLayoutComponent`:\n\n```tsx\n// URL: /route-a\n<PathlessLayoutComponent>\n <RouteAComponent />\n</PathlessLayoutComponent>\n\n// URL: /route-b\n<PathlessLayoutComponent>\n <RouteBComponent />\n</PathlessLayoutComponent>\n```\n\n## Non-Nested Routes\n\nBuilding non-nested routes in code-based routing does not require using a trailing `_` in the path, but does require you to build your route and route tree with the right paths and nesting. Let's consider the route tree where we want the post editor to **not** be nested under the posts route:\n\n- `/posts_/$postId/edit`\n- `/posts`\n - `$postId`\n\nTo do this we need to build a separate route for the post editor and include the entire path in the `path` option from the root of where we want the route to be nested (in this case, the root):\n\n```tsx\n// The posts editor route is nested under the root route\nconst postEditorRoute = createRoute({\n getParentRoute: () => rootRoute,\n // The path includes the entire path we need to match\n path: 'posts/$postId/edit',\n})\n\nconst postsRoute = createRoute({\n getParentRoute: () => rootRoute,\n path: 'posts',\n})\n\nconst postRoute = createRoute({\n getParentRoute: () => postsRoute,\n path: '$postId',\n})\n\nconst routeTree = rootRoute.addChildren([\n // The post editor route is nested under the root route\n postEditorRoute,\n postsRoute.addChildren([postRoute]),\n])\n```\n\n# File-Based Routing\n\nMost of the TanStack Router documentation is written for file-based routing and is intended to help you understand in more detail how to configure file-based routing and the technical details behind how it works. While file-based routing is the preferred and recommended way to configure TanStack Router, you can also use [code-based routing](../code-based-routing.md) if you prefer.\n\n## What is File-Based Routing?\n\nFile-based routing is a way to configure your routes using the filesystem. Instead of defining your route structure via code, you can define your routes using a series of files and directories that represent the route hierarchy of your application. This brings a number of benefits:\n\n- **Simplicity**: File-based routing is visually intuitive and easy to understand for both new and experienced developers.\n- **Organization**: Routes are organized in a way that mirrors the URL structure of your application.\n- **Scalability**: As your application grows, file-based routing makes it easy to add new routes and maintain existing ones.\n- **Code-Splitting**: File-based routing allows TanStack Router to automatically code-split your routes for better performance.\n- **Type-Safety**: File-based routing raises the ceiling on type-safety by generating managing type linkages for your routes, which can otherwise be a tedious process via code-based routing.\n- **Consistency**: File-based routing enforces a consistent structure for your routes, making it easier to maintain and update your application and move from one project to another.\n\n## `/`s or `.`s?\n\nWhile directories have long been used to represent route hierarchy, file-based routing introduces an additional concept of using the `.` character in the file-name to denote a route nesting. This allows you to avoid creating directories for few deeply nested routes and continue to use directories for wider route hierarchies. Let's take a look at some examples!\n\n## Directory Routes\n\nDirectories can be used to denote route hierarchy, which can be useful for organizing multiple routes into logical groups and also cutting down on the filename length for large groups of deeply nested routes.\n\nSee the example below:\n\n| Filename | Route Path | Component Output |\n| ----------------------- | ------------------------- | --------------------------------- |\n| \u02A6 `__root.tsx` | | `<Root>` |\n| \u02A6 `index.tsx` | `/` (exact) | `<Root><RootIndex>` |\n| \u02A6 `about.tsx` | `/about` | `<Root><About>` |\n| \u02A6 `posts.tsx` | `/posts` | `<Root><Posts>` |\n| \uD83D\uDCC2 `posts` | | |\n| \u2504 \u02A6 `index.tsx` | `/posts` (exact) | `<Root><Posts><PostsIndex>` |\n| \u2504 \u02A6 `$postId.tsx` | `/posts/$postId` | `<Root><Posts><Post>` |\n| \uD83D\uDCC2 `posts_` | | |\n| \u2504 \uD83D\uDCC2 `$postId` | | |\n| \u2504 \u2504 \u02A6 `edit.tsx` | `/posts/$postId/edit` | `<Root><EditPost>` |\n| \u02A6 `settings.tsx` | `/settings` | `<Root><Settings>` |\n| \uD83D\uDCC2 `settings` | | `<Root><Settings>` |\n| \u2504 \u02A6 `profile.tsx` | `/settings/profile` | `<Root><Settings><Profile>` |\n| \u2504 \u02A6 `notifications.tsx` | `/settings/notifications` | `<Root><Settings><Notifications>` |\n| \u02A6 `_pathlessLayout.tsx` | | `<Root><PathlessLayout>` |\n| \uD83D\uDCC2 `_pathlessLayout` | | |\n| \u2504 \u02A6 `route-a.tsx` | `/route-a` | `<Root><PathlessLayout><RouteA>` |\n| \u2504 \u02A6 `route-b.tsx` | `/route-b` | `<Root><PathlessLayout><RouteB>` |\n| \uD83D\uDCC2 `files` | | |\n| \u2504 \u02A6 `$.tsx` | `/files/$` | `<Root><Files>` |\n| \uD83D\uDCC2 `account` | | |\n| \u2504 \u02A6 `route.tsx` | `/account` | `<Root><Account>` |\n| \u2504 \u02A6 `overview.tsx` | `/account/overview` | `<Root><Account><Overview>` |\n\n## Flat Routes\n\nFlat routing gives you the ability to use `.`s to denote route nesting levels.\n\nThis can be useful when you have a large number of uniquely deeply nested routes and want to avoid creating directories for each one:\n\nSee the example below:\n\n| Filename | Route Path | Component Output |\n| ------------------------------- | ------------------------- | --------------------------------- |\n| \u02A6 `__root.tsx` | | `<Root>` |\n| \u02A6 `index.tsx` | `/` (exact) | `<Root><RootIndex>` |\n| \u02A6 `about.tsx` | `/about` | `<Root><About>` |\n| \u02A6 `posts.tsx` | `/posts` | `<Root><Posts>` |\n| \u02A6 `posts.index.tsx` | `/posts` (exact) | `<Root><Posts><PostsIndex>` |\n| \u02A6 `posts.$postId.tsx` | `/posts/$postId` | `<Root><Posts><Post>` |\n| \u02A6 `posts_.$postId.edit.tsx` | `/posts/$postId/edit` | `<Root><EditPost>` |\n| \u02A6 `settings.tsx` | `/settings` | `<Root><Settings>` |\n| \u02A6 `settings.profile.tsx` | `/settings/profile` | `<Root><Settings><Profile>` |\n| \u02A6 `settings.notifications.tsx` | `/settings/notifications` | `<Root><Settings><Notifications>` |\n| \u02A6 `_pathlessLayout.tsx` | | `<Root><PathlessLayout>` |\n| \u02A6 `_pathlessLayout.route-a.tsx` | `/route-a` | `<Root><PathlessLayout><RouteA>` |\n| \u02A6 `_pathlessLayout.route-b.tsx` | `/route-b` | `<Root><PathlessLayout><RouteB>` |\n| \u02A6 `files.$.tsx` | `/files/$` | `<Root><Files>` |\n| \u02A6 `account.tsx` | `/account` | `<Root><Account>` |\n| \u02A6 `account.overview.tsx` | `/account/overview` | `<Root><Account><Overview>` |\n\n## Mixed Flat and Directory Routes\n\nIt's extremely likely that a 100% directory or flat route structure won't be the best fit for your project, which is why TanStack Router allows you to mix both flat and directory routes together to create a route tree that uses the best of both worlds where it makes sense:\n\nSee the example below:\n\n| Filename | Route Path | Component Output |\n| ------------------------------ | ------------------------- | --------------------------------- |\n| \u02A6 `__root.tsx` | | `<Root>` |\n| \u02A6 `index.tsx` | `/` (exact) | `<Root><RootIndex>` |\n| \u02A6 `about.tsx` | `/about` | `<Root><About>` |\n| \u02A6 `posts.tsx` | `/posts` | `<Root><Posts>` |\n| \uD83D\uDCC2 `posts` | | |\n| \u2504 \u02A6 `index.tsx` | `/posts` (exact) | `<Root><Posts><PostsIndex>` |\n| \u2504 \u02A6 `$postId.tsx` | `/posts/$postId` | `<Root><Posts><Post>` |\n| \u2504 \u02A6 `$postId.edit.tsx` | `/posts/$postId/edit` | `<Root><Posts><Post><EditPost>` |\n| \u02A6 `settings.tsx` | `/settings` | `<Root><Settings>` |\n| \u02A6 `settings.profile.tsx` | `/settings/profile` | `<Root><Settings><Profile>` |\n| \u02A6 `settings.notifications.tsx` | `/settings/notifications` | `<Root><Settings><Notifications>` |\n| \u02A6 `account.tsx` | `/account` | `<Root><Account>` |\n| \u02A6 `account.overview.tsx` | `/account/overview` | `<Root><Account><Overview>` |\n\nBoth flat and directory routes can be mixed together to create a route tree that uses the best of both worlds where it makes sense.\n\n> [!TIP]\n> If you find that the default file-based routing structure doesn't fit your needs, you can always use [Virtual File Routes](../virtual-file-routes.md) to control the source of your routes whilst still getting the awesome performance benefits of file-based routing.\n\n## Getting started with File-Based Routing\n\nTo get started with file-based routing, you'll need to configure your project's bundler to use the TanStack Router Plugin or the TanStack Router CLI.\n\nTo enable file-based routing, you'll need to be using React with a supported bundler. See if your bundler is listed in the configuration guides below.\n\n[//]: # 'SupportedBundlersList'\n\n- [Installation with Vite](../../installation/with-vite)\n- [Installation with Rspack/Rsbuild](../../installation/with-rspack)\n- [Installation with Webpack](../../installation/with-webpack)\n- [Installation with Esbuild](../../installation/with-esbuild)\n\n[//]: # 'SupportedBundlersList'\n\nWhen using TanStack Router's file-based routing through one of the supported bundlers, our plugin will **automatically generate your route configuration through your bundler's dev and build processes**. It is the easiest way to use TanStack Router's route generation features.\n\nIf your bundler is not yet supported, you can reach out to us on Discord or GitHub to let us know.\n\n# File Naming Conventions\n\nFile-based routing requires that you follow a few simple file naming conventions to ensure that your routes are generated correctly. The concepts these conventions enable are covered in detail in the [Route Trees & Nesting](../route-trees.md) guide.\n\n| Feature | Description |\n| ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| **`__root.tsx`** | The root route file must be named `__root.tsx` and must be placed in the root of the configured `routesDirectory`. |\n| **`.` Separator** | Routes can use the `.` character to denote a nested route. For example, `blog.post` will be generated as a child of `blog`. |\n| **`$` Token** | Route segments with the `$` token are parameterized and will extract the value from the URL pathname as a route `param`. |\n| **`_` Prefix** | Route segments with the `_` prefix are considered to be pathless layout routes and will not be used when matching its child routes against the URL pathname. |\n| **`_` Suffix** | Route segments with the `_` suffix exclude the route from being nested under any parent routes. |\n| **`-` Prefix** | Files and folders with the `-` prefix are excluded from the route tree. They will not be added to the `routeTree.gen.ts` file and can be used to colocate logic in route folders. |\n| **`(folder)` folder name pattern** | A folder that matches this pattern is treated as a **route group**, preventing the folder from being included in the route's URL path. |\n| **`[x]` Escaping** | Square brackets escape special characters in filenames that would otherwise have routing meaning. For example, `script[.]js.tsx` becomes `/script.js` and `api[.]v1.tsx` becomes `/api.v1`. |\n| **`index` Token** | Route segments ending with the `index` token (before any file extensions) will match the parent route when the URL pathname matches the parent route exactly. This can be configured via the `indexToken` configuration option, see [options](../../../../api/file-based-routing.md#indextoken). |\n| **`.route.tsx` File Type** | When using directories to organise routes, the `route` suffix can be used to create a route file at the directory's path. For example, `blog.post.route.tsx` or `blog/post/route.tsx` can be used as the route file for the `/blog/post` route. This can be configured via the `routeToken` configuration option, see [options](../../../../api/file-based-routing.md#routetoken). |\n\n> **\uD83D\uDCA1 Remember:** The file-naming conventions for your project could be affected by what [options](../../../../api/file-based-routing.md) are configured.\n\n> [!NOTE] To escape a trailing underscore, for example `/posts[_].tsx`, usage of the upgraded [Non-Nested Routes](../routing-concepts#non-nested-routes) is required.\n\n## Dynamic Path Params\n\nDynamic path params can be used in both flat and directory routes to create routes that can match a dynamic segment of the URL path. Dynamic path params are denoted by the `$` character in the filename:\n\n| Filename | Route Path | Component Output |\n| --------------------- | ---------------- | --------------------- |\n| ... | ... | ... |\n| \u02A6 `posts.$postId.tsx` | `/posts/$postId` | `<Root><Posts><Post>` |\n\nWe'll learn more about dynamic path params in the [Path Params](../../guide/path-params.md) guide.\n\n## Pathless Routes\n\nPathless routes wrap child routes with either logic or a component without requiring a URL path. Non-path routes are denoted by the `_` character in the filename:\n\n| Filename | Route Path | Component Output |\n| -------------- | ---------- | ---------------- |\n| \u02A6 `_app.tsx` | | |\n| \u02A6 `_app.a.tsx` | /a | `<Root><App><A>` |\n| \u02A6 `_app.b.tsx` | /b | `<Root><App><B>` |\n\nTo learn more about pathless routes, see the [Routing Concepts - Pathless Routes](../routing-concepts.md#pathless-layout-routes) guide.\n\n# Route Matching\n\nRoute matching follows a consistent and predictable pattern. This guide will explain how route trees are matched.\n\nWhen TanStack Router processes your route tree, all of your routes are automatically sorted to match the most specific routes first. This means that regardless of the order your route tree is defined, routes will always be sorted in this order:\n\n- Index Route\n- Static Routes (most specific to least specific)\n- Dynamic Routes (longest to shortest)\n- Splat/Wildcard Routes\n\nConsider the following pseudo route tree:\n\n```\nRoot\n - blog\n - $postId\n - /\n - new\n - /\n - *\n - about\n - about/us\n```\n\nAfter sorting, this route tree will become:\n\n```\nRoot\n - /\n - about/us\n - about\n - blog\n - /\n - new\n - $postId\n - *\n```\n\nThis final order represents the order in which routes will be matched based on specificity.\n\nUsing that route tree, let's follow the matching process for a few different URLs:\n\n- `/blog`\n ```\n Root\n \u274C /\n \u274C about/us\n \u274C about\n \u23E9 blog\n \u2705 /\n - new\n - $postId\n - *\n ```\n- `/blog/my-post`\n ```\n Root\n \u274C /\n \u274C about/us\n \u274C about\n \u23E9 blog\n \u274C /\n \u274C new\n \u2705 $postId\n - *\n ```\n- `/`\n ```\n Root\n \u2705 /\n - about/us\n - about\n - blog\n - /\n - new\n - $postId\n - *\n ```\n- `/not-a-route`\n ```\n Root\n \u274C /\n \u274C about/us\n \u274C about\n \u274C blog\n - /\n - new\n - $postId\n \u2705 *\n ```\n\n# Route Trees\n\nTanStack Router uses a nested route tree to match up the URL with the correct component tree to render.\n\nTo build a route tree, TanStack Router supports:\n\n- [File-Based Routing](../file-based-routing.md)\n- [Code-Based Routing](../code-based-routing.md)\n\nBoth methods support the exact same core features and functionality, but **file-based routing requires less code for the same or better results**. For this reason, **file-based routing is the preferred and recommended way** to configure TanStack Router. Most of the documentation is written from the perspective of file-based routing.\n\n## Route Trees\n\nNested routing is a powerful concept that allows you to use a URL to render a nested component tree. For example, given the URL of `/blog/posts/123`, you could create a route hierarchy that looks like this:\n\n```tsx\n\u251C\u2500\u2500 blog\n\u2502 \u251C\u2500\u2500 posts\n\u2502 \u2502 \u251C\u2500\u2500 $postId\n```\n\nAnd render a component tree that looks like this:\n\n```tsx\n<Blog>\n <Posts>\n <Post postId=\"123\" />\n </Posts>\n</Blog>\n```\n\nLet's take that concept and expand it out to a larger site structure, but with file-names now:\n\n```\n/routes\n\u251C\u2500\u2500 __root.tsx\n\u251C\u2500\u2500 index.tsx\n\u251C\u2500\u2500 about.tsx\n\u251C\u2500\u2500 posts/\n\u2502 \u251C\u2500\u2500 index.tsx\n\u2502 \u251C\u2500\u2500 $postId.tsx\n\u251C\u2500\u2500 posts.$postId.edit.tsx\n\u251C\u2500\u2500 settings/\n\u2502 \u251C\u2500\u2500 profile.tsx\n\u2502 \u251C\u2500\u2500 notifications.tsx\n\u251C\u2500\u2500 _pathlessLayout/\n\u2502 \u251C\u2500\u2500 route-a.tsx\n\u251C\u2500\u2500 \u251C\u2500\u2500 route-b.tsx\n\u251C\u2500\u2500 files/\n\u2502 \u251C\u2500\u2500 $.tsx\n```\n\nThe above is a valid route tree configuration that can be used with TanStack Router! There's a lot of power and convention to unpack with file-based routing, so let's break it down a bit.\n\n## Route Tree Configuration\n\nRoute trees can be configured using a few different ways:\n\n- [Flat Routes](../file-based-routing.md#flat-routes)\n- [Directories](../file-based-routing.md#directory-routes)\n- [Mixed Flat Routes and Directories](../file-based-routing.md#mixed-flat-and-directory-routes)\n- [Virtual File Routes](../virtual-file-routes.md)\n- [Code-Based Routes](../code-based-routing.md)\n\nPlease be sure to check out the full documentation links above for each type of route tree, or just proceed to the next section to get started with file-based routing.\n\n# Routing Concepts\n\nTanStack Router supports a number of powerful routing concepts that allow you to build complex and dynamic routing systems with ease.\n\nEach of these concepts is useful and powerful, and we'll dive into each of them in the following sections.\n\n## Anatomy of a Route\n\nAll other routes, other than the [Root Route](#the-root-route), are configured using the `createFileRoute` function, which provides type safety when using file-based routing:\n\n```tsx\nimport { createFileRoute } from '@tanstack/react-router'\n\nexport const Route = createFileRoute('/')({\n component: PostsComponent,\n})\n```\n\nThe `createFileRoute` function takes a single argument, the file-route's path as a string.\n\n**\u2753\u2753\u2753 \"Wait, you're making me pass the path of the route file to `createFileRoute`?\"**\n\nYes! But don't worry, this path is **automatically written and managed by the router for you via the TanStack Router Bundler Plugin or Router CLI.** So, as you create new routes, move routes around or rename routes, the path will be updated for you automatically.\n\nThe reason for this pathname has everything to do with the magical type safety of TanStack Router. Without this pathname, TypeScript would have no idea what file we're in! (We wish TypeScript had a built-in for this, but they don't yet \uD83E\uDD37\u200D\u2642\uFE0F)\n\n## The Root Route\n\nThe root route is the top-most route in the entire tree and encapsulates all other routes as children.\n\n- It has no path\n- It is **always** matched\n- Its `component` is **always** rendered\n\nEven though it doesn't have a path, the root route has access to all of the same functionality as other routes including:\n\n- components\n- loaders\n- search param validation\n- etc.\n\nTo create a root route, call the `createRootRoute()` function and export it as the `Route` variable in your route file:\n\n```tsx\n// Standard root route\nimport { createRootRoute } from '@tanstack/react-router'\n\nexport const Route = createRootRoute()\n\n// Root route with Context\nimport { createRootRouteWithContext } from '@tanstack/react-router'\nimport type { QueryClient } from '@tanstack/react-query'\n\nexport interface MyRouterContext {\n queryClient: QueryClient\n}\nexport const Route = createRootRouteWithContext<MyRouterContext>()\n```\n\nTo learn more about Context in TanStack Router, see the [Router Context](../../guide/router-context.md) guide.\n\n## Basic Routes\n\nBasic routes match a specific path, for example `/about`, `/settings`, `/settings/notifications` are all basic routes, as they match the path exactly.\n\nLet's take a look at an `/about` route:\n\n```tsx\n// about.tsx\nimport { createFileRoute } from '@tanstack/react-router'\n\nexport const Route = createFileRoute('/about')({\n component: AboutComponent,\n})\n\nfunction AboutComponent() {\n return <div>About</div>\n}\n```\n\nBasic routes are simple and straightforward. They match the path exactly and render the provided component.\n\n## Index Routes\n\nIndex routes specifically target their parent route when it is **matched exactly and no child route is matched**.\n\nLet's take a look at an index route for a `/posts` URL:\n\n```tsx\n// posts.index.tsx\nimport { createFileRoute } from '@tanstack/react-router'\n\n// Note the trailing slash, which is used to target index routes\nexport const Route = createFileRoute('/posts/')({\n component: PostsIndexComponent,\n})\n\nfunction PostsIndexComponent() {\n return <div>Please select a post!</div>\n}\n```\n\nThis route will be matched when the URL is `/posts` exactly.\n\n## Dynamic Route Segments\n\nRoute path segments that start with a `$` followed by a label are dynamic and capture that section of the URL into the `params` object for use in your application. For example, a pathname of `/posts/123` would match the `/posts/$postId` route, and the `params` object would be `{ postId: '123' }`.\n\nThese params are then usable in your route's configuration and components! Let's look at a `posts.$postId.tsx` route:\n\n```tsx\nimport { createFileRoute } from '@tanstack/react-router'\n\nexport const Route = createFileRoute('/posts/$postId')({\n // In a loader\n loader: ({ params }) => fetchPost(params.postId),\n // Or in a component\n component: PostComponent,\n})\n\nfunction PostComponent() {\n // In a component!\n const { postId } = Route.useParams()\n return <div>Post ID: {postId}</div>\n}\n```\n\n> \uD83E\uDDE0 Dynamic segments work at **each** segment of the path. For example, you could have a route with the path of `/posts/$postId/$revisionId` and each `$` segment would be captured into the `params` object.\n\n## Splat / Catch-All Routes\n\nA route with a path of only `$` is called a \"splat\" route because it _always_ captures _any_ remaining section of the URL pathname from the `$` to the end. The captured pathname is then available in the `params` object under the special `_splat` property.\n\nFor example, a route targeting the `files/$` path is a splat route. If the URL pathname is `/files/documents/hello-world`, the `params` object would contain `documents/hello-world` under the special `_splat` property:\n\n```js\n{\n '_splat': 'documents/hello-world'\n}\n```\n\n> \u26A0\uFE0F In v1 of the router, splat routes are also denoted with a `*` instead of a `_splat` key for backwards compatibility. This will be removed in v2.\n\n> \uD83E\uDDE0 Why use `$`? Thanks to tools like Remix, we know that despite `*`s being the most common character to represent a wildcard, they do not play nice with filenames or CLI tools, so just like them, we decided to use `$` instead.\n\n## Optional Path Parameters\n\nOptional path parameters allow you to define route segments that may or may not be present in the URL. They use the `{-$paramName}` syntax and provide flexible routing patterns where certain parameters are optional.\n\n```tsx\n// posts.{-$category}.tsx - Optional category parameter\nimport { createFileRoute } from '@tanstack/react-router'\n\nexport const Route = createFileRoute('/posts/{-$category}')({\n component: PostsComponent,\n})\n\nfunction PostsComponent() {\n const { category } = Route.useParams()\n\n return <div>{category ? `Posts in ${category}` : 'All Posts'}</div>\n}\n```\n\nThis route will match both `/posts` (category is `undefined`) and `/posts/tech` (category is `\"tech\"`).\n\nYou can also define multiple optional parameters in a single route:\n\n```tsx\n// posts.{-$category}.{-$slug}.tsx\nexport const Route = createFileRoute('/posts/{-$category}/{-$slug}')({\n component: PostsComponent,\n})\n```\n\nThis route matches `/posts`, `/posts/tech`, and `/posts/tech/hello-world`.\n\n> \uD83E\uDDE0 Routes with optional parameters are ranked lower in priority than exact matches, ensuring that more specific routes like `/posts/featured` are matched before `/posts/{-$category}`.\n\n## Layout Routes\n\nLayout routes are used to wrap child routes with additional components and logic. They are useful for:\n\n- Wrapping child routes with a layout component\n- Enforcing a `loader` requirement before displaying any child routes\n- Validating and providing search params to child routes\n- Providing fallbacks for error components or pending elements to child routes\n- Providing shared context to all child routes\n- And more!\n\nLet's take a look at an example layout route called `app.tsx`:\n\n```\nroutes/\n\u251C\u2500\u2500 app.tsx\n\u251C\u2500\u2500 app.dashboard.tsx\n\u251C\u2500\u2500 app.settings.tsx\n```\n\nIn the tree above, `app.tsx` is a layout route that wraps two child routes, `app.dashboard.tsx` and `app.settings.tsx`.\n\nThis tree structure is used to wrap the child routes with a layout component:\n\n```tsx\nimport { Outlet, createFileRoute } from '@tanstack/react-router'\n\nexport const Route = createFileRoute('/app')({\n component: AppLayoutComponent,\n})\n\nfunction AppLayoutComponent() {\n return (\n <div>\n <h1>App Layout</h1>\n <Outlet />\n </div>\n )\n}\n```\n\nThe following table shows which component(s) will be rendered based on the URL:\n\n| URL Path | Component |\n| ---------------- | ------------------------ |\n| `/app` | `<AppLayout>` |\n| `/app/dashboard` | `<AppLayout><Dashboard>` |\n| `/app/settings` | `<AppLayout><Settings>` |\n\nSince TanStack Router supports mixed flat and directory routes, you can also express your application's routing using layout routes within directories:\n\n```\nroutes/\n\u251C\u2500\u2500 app/\n\u2502 \u251C\u2500\u2500 route.tsx\n\u2502 \u251C\u2500\u2500 dashboard.tsx\n\u2502 \u251C\u2500\u2500 settings.tsx\n```\n\nIn this nested tree, the `app/route.tsx` file is a configuration for the layout route that wraps two child routes, `app/dashboard.tsx` and `app/settings.tsx`.\n\nLayout Routes also let you enforce component and loader logic for Dynamic Route Segments:\n\n```\nroutes/\n\u251C\u2500\u2500 app/users/\n\u2502 \u251C\u2500\u2500 $userId/\n| | \u251C\u2500\u2500 route.tsx\n| | \u251C\u2500\u2500 index.tsx\n| | \u251C\u2500\u2500 edit.tsx\n```\n\n## Pathless Layout Routes\n\nLike [Layout Routes](#layout-routes), Pathless Layout Routes are used to wrap child routes with additional components and logic. However, pathless layout routes do not require a matching `path` in the URL and are used to wrap child routes with additional components and logic without requiring a matching `path` in the URL.\n\nPathless Layout Routes are prefixed with an underscore (`_`) to denote that they are \"pathless\".\n\n> \uD83E\uDDE0 The part of the path after the `_` prefix is used as the route's ID and is required because every route must be uniquely identifiable, especially when using TypeScript so as to avoid type errors and accomplish autocomplete effectively.\n\nLet's take a look at an example route called `_pathlessLayout.tsx`:\n\n```\n\nroutes/\n\u251C\u2500\u2500 _pathlessLayout.tsx\n\u251C\u2500\u2500 _pathlessLayout.a.tsx\n\u251C\u2500\u2500 _pathlessLayout.b.tsx\n\n```\n\nIn the tree above, `_pathlessLayout.tsx` is a pathless layout route that wraps two child routes, `_pathlessLayout.a.tsx` and `_pathlessLayout.b.tsx`.\n\nThe `_pathlessLayout.tsx` route is used to wrap the child routes with a Pathless layout component:\n\n```tsx\nimport { Outlet, createFileRoute } from '@tanstack/react-router'\n\nexport const Route = createFileRoute('/_pathlessLayout')({\n component: PathlessLayoutComponent,\n})\n\nfunction PathlessLayoutComponent() {\n return (\n <div>\n <h1>Pathless layout</h1>\n <Outlet />\n </div>\n )\n}\n```\n\nThe following table shows which component will be rendered based on the URL:\n\n| URL Path | Component |\n| -------- | --------------------- |\n| `/` | `<Index>` |\n| `/a` | `<PathlessLayout><A>` |\n| `/b` | `<PathlessLayout><B>` |\n\nSince TanStack Router supports mixed flat and directory routes, you can also express your application's routing using pathless layout routes within directories:\n\n```\nroutes/\n\u251C\u2500\u2500 _pathlessLayout/\n\u2502 \u251C\u2500\u2500 route.tsx\n\u2502 \u251C\u2500\u2500 a.tsx\n\u2502 \u251C\u2500\u2500 b.tsx\n```\n\nHowever, unlike Layout Routes, since Pathless Layout Routes do match based on URL path segments, this means that these routes do not support [Dynamic Route Segments](#dynamic-route-segments) as part of their path and therefore cannot be matched in the URL.\n\nThis means that you cannot do this:\n\n```\nroutes/\n\u251C\u2500\u2500 _$postId/ \u274C\n\u2502 \u251C\u2500\u2500 ...\n```\n\nRather, you'd have to do this:\n\n```\nroutes/\n\u251C\u2500\u2500 $postId/\n\u251C\u2500\u2500 _postPathlessLayout/ \u2705\n\u2502 \u251C\u2500\u2500 ...\n```\n\n## Non-Nested Routes\n\nNon-nested routes can be created by suffixing a parent file route segment with a `_` and are used to **un-nest** a route from its parents and render its own component tree.\n\nConsider the following flat route tree:\n\n```\nroutes/\n\u251C\u2500\u2500 posts.tsx\n\u251C\u2500\u2500 posts.$postId.tsx\n\u251C\u2500\u2500 posts_.$postId.edit.tsx\n```\n\nThe following table shows which component will be rendered based on the URL:\n\n| URL Path | Component |\n| ----------------- | ---------------------------- |\n| `/posts` | `<Posts>` |\n| `/posts/123` | `<Posts><Post postId=\"123\">` |\n| `/posts/123/edit` | `<PostEditor postId=\"123\">` |\n\n- The `posts.$postId.tsx` route is nested as normal under the `posts.tsx` route and will render `<Posts><Post>`.\n- The `posts_.$postId.edit.tsx` route **does not share** the same `posts` prefix as the other routes and therefore will be treated as if it is a top-level route and will render `<PostEditor>`.\n\n> [!NOTE]\n> While using non-nested routes with file-based routing already works brilliantly, it might misbehave in certain conditions.\n> Many of these limitations have already been addressed and will be released in the next major version of TanStack Router.\n>\n> To start enjoying these benefits early, you can enable the experimental `nonNestedRoutes` flag in the router plugin configuration:\n>\n> ```ts\n> export default defineConfig({\n> plugins: [\n> tanstackRouter({\n> // some config,\n> experimental: {\n> nonNestedRoutes: true,\n> },\n> }),\n> ],\n> })\n> ```\n>\n> _It is important to note that this does bring a slight change in how non-nested routes are referenced in useParams, useNavigate, etc. For this reason this has been released as a feature flag.\n> The trailing underscore is no longer expected in the path:_\n>\n> Previously:\n>\n> ```ts\n> useParams({ from: '/posts_/$postId/edit' })\n> ```\n>\n> Now:\n>\n> ```ts\n> useParams({ from: '/posts/$postId/edit' })\n> ```\n\n## Excluding Files and Folders from Routes\n\nFiles and folders can be excluded from route generation with a `-` prefix attached to the file name. This gives you the ability to colocate logic in the route directories.\n\nConsider the following route tree:\n\n```\nroutes/\n\u251C\u2500\u2500 posts.tsx\n\u251C\u2500\u2500 -posts-table.tsx // \uD83D\uDC48\uD83C\uDFFC ignored\n\u251C\u2500\u2500 -components/ // \uD83D\uDC48\uD83C\uDFFC ignored\n\u2502 \u251C\u2500\u2500 header.tsx // \uD83D\uDC48\uD83C\uDFFC ignored\n\u2502 \u251C\u2500\u2500 footer.tsx // \uD83D\uDC48\uD83C\uDFFC ignored\n\u2502 \u251C\u2500\u2500 ...\n```\n\nWe can import from the excluded files into our posts route\n\n```tsx\nimport { createFileRoute } from '@tanstack/react-router'\nimport { PostsTable } from './-posts-table'\nimport { PostsHeader } from './-components/header'\nimport { PostsFooter } from './-components/footer'\n\nexport const Route = createFileRoute('/posts')({\n loader: () => fetchPosts(),\n component: PostComponent,\n})\n\nfunction PostComponent() {\n const posts = Route.useLoaderData()\n\n return (\n <div>\n <PostsHeader />\n <PostsTable posts={posts} />\n <PostsFooter />\n </div>\n )\n}\n```\n\nThe excluded files will not be added to `routeTree.gen.ts`.\n\n## Pathless Route Group Directories\n\nPathless route group directories use `()` as a way to group routes files together regardless of their path. They are purely organizational and do not affect the route tree or component tree in any way.\n\n```\nroutes/\n\u251C\u2500\u2500 index.tsx\n\u251C\u2500\u2500 (app)/\n\u2502 \u251C\u2500\u2500 dashboard.tsx\n\u2502 \u251C\u2500\u2500 settings.tsx\n\u2502 \u251C\u2500\u2500 users.tsx\n\u251C\u2500\u2500 (auth)/\n\u2502 \u251C\u2500\u2500 login.tsx\n\u2502 \u251C\u2500\u2500 register.tsx\n```\n\nIn the example above, the `app` and `auth` directories are purely organizational and do not affect the route tree or component tree in any way. They are used to group related routes together for easier navigation and organization.\n\nThe following table shows which component will be rendered based on the URL:\n\n| URL Path | Component |\n| ------------ | ------------- |\n| `/` | `<Index>` |\n| `/dashboard` | `<Dashboard>` |\n| `/settings` | `<Settings>` |\n| `/users` | `<Users>` |\n| `/login` | `<Login>` |\n| `/register` | `<Register>` |\n\nAs you can see, the `app` and `auth` directories are purely organizational and do not affect the route tree or component tree in any way.\n\n# Virtual File Routes\n\n> We'd like to thank the Remix team for [pioneering the concept of virtual file routes](https://www.youtube.com/watch?v=fjTX8hQTlEc&t=730s). We've taken inspiration from their work and adapted it to work with TanStack Router's existing file-based route-tree generation.\n\nVirtual file routes are a powerful concept that allows you to build a route tree programmatically using code that references real files in your project. This can be useful if:\n\n- You have an existing route organization that you want to keep.\n- You want to customize the location of your route files.\n- You want to completely override TanStack Router's file-based route generation and build your own convention.\n\nHere's a quick example of using virtual file routes to map a route tree to a set of real files in your project:\n\n```tsx\n// routes.ts\nimport {\n rootRoute,\n route,\n index,\n layout,\n physical,\n} from '@tanstack/virtual-file-routes'\n\nexport const routes = rootRoute('root.tsx', [\n index('index.tsx'),\n layout('pathlessLayout.tsx', [\n route('/dashboard', 'app/dashboard.tsx', [\n index('app/dashboard-index.tsx'),\n route('/invoices', 'app/dashboard-invoices.tsx', [\n index('app/invoices-index.tsx'),\n route('$id', 'app/invoice-detail.tsx'),\n ]),\n ]),\n physical('/posts', 'posts'),\n ]),\n])\n```\n\n## Configuration\n\nVirtual file routes can be configured either via:\n\n- The `TanStackRouter` plugin for Vite/Rspack/Webpack\n- The `tsr.config.json` file for the TanStack Router CLI\n\n## Configuration via the TanStackRouter Plugin\n\nIf you're using the `TanStackRouter` plugin for Vite/Rspack/Webpack, you can configure virtual file routes by passing the path of your routes file to the `virtualRoutesConfig` option when setting up the plugin:\n\n```tsx\n// vite.config.ts\nimport { defineConfig } from 'vite'\nimport react from '@vitejs/plugin-react'\nimport { tanstackRouter } from '@tanstack/router-plugin/vite'\n\nexport default defineConfig({\n plugins: [\n tanstackRouter({\n target: 'react',\n virtualRouteConfig: './routes.ts',\n }),\n react(),\n ],\n})\n```\n\nOr, you choose to define the virtual routes directly in the configuration:\n\n```tsx\n// vite.config.ts\nimport { defineConfig } from 'vite'\nimport react from '@vitejs/plugin-react'\nimport { tanstackRouter } from '@tanstack/router-plugin/vite'\nimport { rootRoute } from '@tanstack/virtual-file-routes'\n\nconst routes = rootRoute('root.tsx', [\n // ... the rest of your virtual route tree\n])\n\nexport default defineConfig({\n plugins: [tanstackRouter({ virtualRouteConfig: routes }), react()],\n})\n```\n\n## Creating Virtual File Routes\n\nTo create virtual file routes, you'll need to import the `@tanstack/virtual-file-routes` package. This package provides a set of functions that allow you to create virtual routes that reference real files in your project. A few utility functions are exported from the package:\n\n- `rootRoute` - Creates a virtual root route.\n- `route` - Creates a virtual route.\n- `index` - Creates a virtual index route.\n- `layout` - Creates a virtual pathless layout route.\n- `physical` - Creates a physical virtual route (more on this later).\n\n## Virtual Root Route\n\nThe `rootRoute` function is used to create a virtual root route. It takes a file name and an array of children routes. Here's an example of a virtual root route:\n\n```tsx\n// routes.ts\nimport { rootRoute } from '@tanstack/virtual-file-routes'\n\nexport const routes = rootRoute('root.tsx', [\n // ... children routes\n])\n```\n\n## Virtual Route\n\nThe `route` function is used to create a virtual route. It takes a path, a file name, and an array of children routes. Here's an example of a virtual route:\n\n```tsx\n// routes.ts\nimport { route } from '@tanstack/virtual-file-routes'\n\nexport const routes = rootRoute('root.tsx', [\n route('/about', 'about.tsx', [\n // ... children routes\n ]),\n])\n```\n\nYou can also define a virtual route without a file name. This allows to set a common path prefix for its children:\n\n```tsx\n// routes.ts\nimport { route } from '@tanstack/virtual-file-routes'\n\nexport const routes = rootRoute('root.tsx', [\n route('/hello', [\n route('/world', 'world.tsx'), // full path will be \"/hello/world\"\n route('/universe', 'universe.tsx'), // full path will be \"/hello/universe\"\n ]),\n])\n```\n\n## Virtual Index Route\n\nThe `index` function is used to create a virtual index route. It takes a file name. Here's an example of a virtual index route:\n\n```tsx\nimport { index } from '@tanstack/virtual-file-routes'\n\nconst routes = rootRoute('root.tsx', [index('index.tsx')])\n```\n\n## Virtual Pathless Route\n\nThe `layout` function is used to create a virtual pathless route. It takes a file name, an array of children routes, and an optional pathless ID. Here's an example of a virtual pathless route:\n\n```tsx\n// routes.ts\nimport { layout } from '@tanstack/virtual-file-routes'\n\nexport const routes = rootRoute('root.tsx', [\n layout('pathlessLayout.tsx', [\n // ... children routes\n ]),\n])\n```\n\nYou can also specify a pathless ID to give the route a unique identifier that is different from the filename:\n\n```tsx\n// routes.ts\nimport { layout } from '@tanstack/virtual-file-routes'\n\nexport const routes = rootRoute('root.tsx', [\n layout('my-pathless-layout-id', 'pathlessLayout.tsx', [\n // ... children routes\n ]),\n])\n```\n\n## Physical Virtual Routes\n\nPhysical virtual routes are a way to \"mount\" a directory of good ol' TanStack Router File Based routing convention under a specific URL path. This can be useful if you are using virtual routes to customize a small portion of your route tree high up in the hierarchy, but want to use the standard file-based routing convention for sub-routes and directories.\n\nConsider the following file structure:\n\n```\n/routes\n\u251C\u2500\u2500 root.tsx\n\u251C\u2500\u2500 index.tsx\n\u251C\u2500\u2500 pathlessLayout.tsx\n\u251C\u2500\u2500 app\n\u2502 \u251C\u2500\u2500 dashboard.tsx\n\u2502 \u251C\u2500\u2500 dashboard-index.tsx\n\u2502 \u251C\u2500\u2500 dashboard-invoices.tsx\n\u2502 \u251C\u2500\u2500 invoices-index.tsx\n\u2502 \u251C\u2500\u2500 invoice-detail.tsx\n\u2514\u2500\u2500 posts\n \u251C\u2500\u2500 index.tsx\n \u251C\u2500\u2500 $postId.tsx\n \u251C\u2500\u2500 $postId.edit.tsx\n \u251C\u2500\u2500 comments/\n \u2502 \u251C\u2500\u2500 index.tsx\n \u2502 \u251C\u2500\u2500 $commentId.tsx\n \u2514\u2500\u2500 likes/\n \u251C\u2500\u2500 index.tsx\n \u251C\u2500\u2500 $likeId.tsx\n```\n\nLet's use virtual routes to customize our route tree for everything but `posts`, then use physical virtual routes to mount the `posts` directory under the `/posts` path:\n\n```tsx\n// routes.ts\nexport const routes = rootRoute('root.tsx', [\n // Set up your virtual routes as normal\n index('index.tsx'),\n layout('pathlessLayout.tsx', [\n route('/dashboard', 'app/dashboard.tsx', [\n index('app/dashboard-index.tsx'),\n route('/invoices', 'app/dashboard-invoices.tsx', [\n index('app/invoices-index.tsx'),\n route('$id', 'app/invoice-detail.tsx'),\n ]),\n ]),\n // Mount the `posts` directory under the `/posts` path\n physical('/posts', 'posts'),\n ]),\n])\n```\n\n## Virtual Routes inside of TanStack Router File Based routing\n\nThe previous section showed you how you can use TanStack Router's File Based routing convention inside of a virtual route configuration.\nHowever, the opposite is possible as well. \nYou can configure the main part of your app's route tree using TanStack Router's File Based routing convention and opt into virtual route configuration for specific subtrees.\n\nConsider the following file structure:\n\n```\n/routes\n\u251C\u2500\u2500 __root.tsx\n\u251C\u2500\u2500 foo\n\u2502 \u251C\u2500\u2500 bar\n\u2502 \u2502 \u251C\u2500\u2500 __virtual.ts\n\u2502 \u2502 \u251C\u2500\u2500 details.tsx\n\u2502 \u2502 \u251C\u2500\u2500 home.tsx\n\u2502 \u2502 \u2514\u2500\u2500 route.ts\n\u2502 \u2514\u2500\u2500 bar.tsx\n\u2514\u2500\u2500 index.tsx\n```\n\nLet's look at the `bar` directory which contains a special file named `__virtual.ts`. This file instructs the generator to switch over to virtual file route configuration for this directory (and its child directories).\n\n`__virtual.ts` configures the virtual routes for that particular subtree of the route tree. It uses the same API as explained above, with the only difference being that no `rootRoute` is defined for that subtree:\n\n```tsx\n// routes/foo/bar/__virtual.ts\nimport {\n defineVirtualSubtreeConfig,\n index,\n route,\n} from '@tanstack/virtual-file-routes'\n\nexport default defineVirtualSubtreeConfig([\n index('home.tsx'),\n route('$id', 'details.tsx'),\n])\n```\n\nThe helper function `defineVirtualSubtreeConfig` is closely modeled after vite's `defineConfig` and allows you to define a subtree configuration via a default export. The default export can either be\n\n- a subtree config object\n- a function returning a subtree config object\n- an async function returning a subtree config object\n\n## Inception\n\nYou can mix and match TanStack Router's File Based routing convention and virtual route configuration however you like. \nLet's go deeper! \nCheck out the following example that starts off using File Based routing convention, switches over to virtual route configuration for `/posts`, switches back to File Based routing convention for `/posts/lets-go` only to switch over to virtual route configuration again for `/posts/lets-go/deeper`.\n\n```\n\u251C\u2500\u2500 __root.tsx\n\u251C\u2500\u2500 index.tsx\n\u251C\u2500\u2500 posts\n\u2502 \u251C\u2500\u2500 __virtual.ts\n\u2502 \u251C\u2500\u2500 details.tsx\n\u2502 \u251C\u2500\u2500 home.tsx\n\u2502 \u2514\u2500\u2500 lets-go\n\u2502 \u251C\u2500\u2500 deeper\n\u2502 \u2502 \u251C\u2500\u2500 __virtual.ts\n\u2502 \u2502 \u2514\u2500\u2500 home.tsx\n\u2502 \u2514\u2500\u2500 index.tsx\n\u2514\u2500\u2500 posts.tsx\n```\n\n## Configuration via the TanStack Router CLI\n\nIf you're using the TanStack Router CLI, you can configure virtual file routes by defining the path to your routes file in the `tsr.config.json` file:\n\n```json\n// tsr.config.json\n{\n \"virtualRouteConfig\": \"./routes.ts\"\n}\n```\n\nOr you can define the virtual routes directly in the configuration, while much less common allows you to configure them via the TanStack Router CLI by adding a `virtualRouteConfig` object to your `tsr.config.json` file and defining your virtual routes and passing the resulting JSON that is generated by calling the actual `rootRoute`/`route`/`index`/etc functions from the `@tanstack/virtual-file-routes` package:\n\n```json\n// tsr.config.json\n{\n \"virtualRouteConfig\": {\n \"type\": \"root\",\n \"file\": \"root.tsx\",\n \"children\": [\n {\n \"type\": \"index\",\n \"file\": \"home.tsx\"\n },\n {\n \"type\": \"route\",\n \"file\": \"posts/posts.tsx\",\n \"path\": \"/posts\",\n \"children\": [\n {\n \"type\": \"index\",\n \"file\": \"posts/posts-home.tsx\"\n },\n {\n \"type\": \"route\",\n \"file\": \"posts/posts-detail.tsx\",\n \"path\": \"$postId\"\n }\n ]\n },\n {\n \"type\": \"layout\",\n \"id\": \"first\",\n \"file\": \"layout/first-pathless-layout.tsx\",\n \"children\": [\n {\n \"type\": \"layout\",\n \"id\": \"second\",\n \"file\": \"layout/second-pathless-layout.tsx\",\n \"children\": [\n {\n \"type\": \"route\",\n \"file\": \"a.tsx\",\n \"path\": \"/route-a\"\n },\n {\n \"type\": \"route\",\n \"file\": \"b.tsx\",\n \"path\": \"/route-b\"\n }\n ]\n }\n ]\n }\n ]\n }\n}\n```\n\n";
1
+ declare const _default: "# Code-Based Routing\n\n> [!TIP]\n> Code-based routing is not recommended for most applications. It is recommended to use [File-Based Routing](../file-based-routing.md) instead.\n\n## \u26A0\uFE0F Before You Start\n\n- If you're using [File-Based Routing](../file-based-routing.md), **skip this guide**.\n- If you still insist on using code-based routing, you must read the [Routing Concepts](../routing-concepts.md) guide first, as it also covers core concepts of the router.\n\n## Route Trees\n\nCode-based routing is no different from file-based routing in that it uses the same route tree concept to organize, match and compose matching routes into a component tree. The only difference is that instead of using the filesystem to organize your routes, you use code.\n\nLet's consider the same route tree from the [Route Trees & Nesting](../route-trees.md#route-trees) guide, and convert it to code-based routing:\n\nHere is the file-based version:\n\n```\nroutes/\n\u251C\u2500\u2500 __root.tsx\n\u251C\u2500\u2500 index.tsx\n\u251C\u2500\u2500 about.tsx\n\u251C\u2500\u2500 posts/\n\u2502 \u251C\u2500\u2500 index.tsx\n\u2502 \u251C\u2500\u2500 $postId.tsx\n\u251C\u2500\u2500 posts.$postId.edit.tsx\n\u251C\u2500\u2500 settings/\n\u2502 \u251C\u2500\u2500 profile.tsx\n\u2502 \u251C\u2500\u2500 notifications.tsx\n\u251C\u2500\u2500 _pathlessLayout.tsx\n\u251C\u2500\u2500 _pathlessLayout/\n\u2502 \u251C\u2500\u2500 route-a.tsx\n\u251C\u2500\u2500 \u251C\u2500\u2500 route-b.tsx\n\u251C\u2500\u2500 files/\n\u2502 \u251C\u2500\u2500 $.tsx\n```\n\nAnd here is a summarized code-based version:\n\n```tsx\nimport { createRootRoute, createRoute } from '@tanstack/react-router'\n\nconst rootRoute = createRootRoute()\n\nconst indexRoute = createRoute({\n getParentRoute: () => rootRoute,\n path: '/',\n})\n\nconst aboutRoute = createRoute({\n getParentRoute: () => rootRoute,\n path: 'about',\n})\n\nconst postsRoute = createRoute({\n getParentRoute: () => rootRoute,\n path: 'posts',\n})\n\nconst postsIndexRoute = createRoute({\n getParentRoute: () => postsRoute,\n path: '/',\n})\n\nconst postRoute = createRoute({\n getParentRoute: () => postsRoute,\n path: '$postId',\n})\n\nconst postEditorRoute = createRoute({\n getParentRoute: () => rootRoute,\n path: 'posts/$postId/edit',\n})\n\nconst settingsRoute = createRoute({\n getParentRoute: () => rootRoute,\n path: 'settings',\n})\n\nconst profileRoute = createRoute({\n getParentRoute: () => settingsRoute,\n path: 'profile',\n})\n\nconst notificationsRoute = createRoute({\n getParentRoute: () => settingsRoute,\n path: 'notifications',\n})\n\nconst pathlessLayoutRoute = createRoute({\n getParentRoute: () => rootRoute,\n id: 'pathlessLayout',\n})\n\nconst pathlessLayoutARoute = createRoute({\n getParentRoute: () => pathlessLayoutRoute,\n path: 'route-a',\n})\n\nconst pathlessLayoutBRoute = createRoute({\n getParentRoute: () => pathlessLayoutRoute,\n path: 'route-b',\n})\n\nconst filesRoute = createRoute({\n getParentRoute: () => rootRoute,\n path: 'files/$',\n})\n```\n\n## Anatomy of a Route\n\nAll other routes other than the root route are configured using the `createRoute` function:\n\n```tsx\nconst route = createRoute({\n getParentRoute: () => rootRoute,\n path: '/posts',\n component: PostsComponent,\n})\n```\n\nThe `getParentRoute` option is a function that returns the parent route of the route you're creating.\n\n**\u2753\u2753\u2753 \"Wait, you're making me pass the parent route for every route I make?\"**\n\nAbsolutely! The reason for passing the parent route has **everything to do with the magical type safety** of TanStack Router. Without the parent route, TypeScript would have no idea what types to supply your route with!\n\n> [!IMPORTANT]\n> For every route that's **NOT** the **Root Route** or a **Pathless Layout Route**, a `path` option is required. This is the path that will be matched against the URL pathname to determine if the route is a match.\n\nWhen configuring route `path` option on a route, it ignores leading and trailing slashes (this does not include \"index\" route paths `/`). You can include them if you want, but they will be normalized internally by TanStack Router. Here is a table of valid paths and what they will be normalized to:\n\n| Path | Normalized Path |\n| -------- | --------------- |\n| `/` | `/` |\n| `/about` | `about` |\n| `about/` | `about` |\n| `about` | `about` |\n| `$` | `$` |\n| `/$` | `$` |\n| `/$/` | `$` |\n\n## Manually building the route tree\n\nWhen building a route tree in code, it's not enough to define the parent route of each route. You must also construct the final route tree by adding each route to its parent route's `children` array. This is because the route tree is not built automatically for you like it is in file-based routing.\n\n```tsx\n/* prettier-ignore */\nconst routeTree = rootRoute.addChildren([\n indexRoute,\n aboutRoute,\n postsRoute.addChildren([\n postsIndexRoute,\n postRoute,\n ]),\n postEditorRoute,\n settingsRoute.addChildren([\n profileRoute,\n notificationsRoute,\n ]),\n pathlessLayoutRoute.addChildren([\n pathlessLayoutARoute,\n pathlessLayoutBRoute,\n ]),\n filesRoute.addChildren([\n fileRoute,\n ]),\n])\n/* prettier-ignore-end */\n```\n\nBut before you can go ahead and build the route tree, you need to understand how the Routing Concepts for Code-Based Routing work.\n\n## Routing Concepts for Code-Based Routing\n\nBelieve it or not, file-based routing is really a superset of code-based routing and uses the filesystem and a bit of code-generation abstraction on top of it to generate this structure you see above automatically.\n\nWe're going to assume you've read the [Routing Concepts](../routing-concepts.md) guide and are familiar with each of these main concepts:\n\n- The Root Route\n- Basic Routes\n- Index Routes\n- Dynamic Route Segments\n- Splat / Catch-All Routes\n- Layout Routes\n- Pathless Routes\n- Non-Nested Routes\n\nNow, let's take a look at how to create each of these route types in code.\n\n## The Root Route\n\nCreating a root route in code-based routing is thankfully the same as doing so in file-based routing. Call the `createRootRoute()` function.\n\nUnlike file-based routing however, you do not need to export the root route if you don't want to. It's certainly not recommended to build an entire route tree and application in a single file (although you can and we do this in the examples to demonstrate routing concepts in brevity).\n\n```tsx\n// Standard root route\nimport { createRootRoute } from '@tanstack/react-router'\n\nconst rootRoute = createRootRoute()\n\n// Root route with Context\nimport { createRootRouteWithContext } from '@tanstack/react-router'\nimport type { QueryClient } from '@tanstack/react-query'\n\nexport interface MyRouterContext {\n queryClient: QueryClient\n}\nconst rootRoute = createRootRouteWithContext<MyRouterContext>()\n```\n\nTo learn more about Context in TanStack Router, see the [Router Context](../../guide/router-context.md) guide.\n\n## Basic Routes\n\nTo create a basic route, simply provide a normal `path` string to the `createRoute` function:\n\n```tsx\nconst aboutRoute = createRoute({\n getParentRoute: () => rootRoute,\n path: 'about',\n})\n```\n\nSee, it's that simple! The `aboutRoute` will match the URL `/about`.\n\n## Index Routes\n\nUnlike file-based routing, which uses the `index` filename to denote an index route, code-based routing uses a single slash `/` to denote an index route. For example, the `posts.index.tsx` file from our example route tree above would be represented in code-based routing like this:\n\n```tsx\nconst postsRoute = createRoute({\n getParentRoute: () => rootRoute,\n path: 'posts',\n})\n\nconst postsIndexRoute = createRoute({\n getParentRoute: () => postsRoute,\n // Notice the single slash `/` here\n path: '/',\n})\n```\n\nSo, the `postsIndexRoute` will match the URL `/posts/` (or `/posts`).\n\n## Dynamic Route Segments\n\nDynamic route segments work exactly the same in code-based routing as they do in file-based routing. Simply prefix a segment of the path with a `$` and it will be captured into the `params` object of the route's `loader` or `component`:\n\n```tsx\nconst postIdRoute = createRoute({\n getParentRoute: () => postsRoute,\n path: '$postId',\n // In a loader\n loader: ({ params }) => fetchPost(params.postId),\n // Or in a component\n component: PostComponent,\n})\n\nfunction PostComponent() {\n const { postId } = postIdRoute.useParams()\n return <div>Post ID: {postId}</div>\n}\n```\n\n> [!TIP]\n> If your component is code-split, you can use the [getRouteApi function](../../guide/code-splitting.md#manually-accessing-route-apis-in-other-files-with-the-getrouteapi-helper) to avoid having to import the `postIdRoute` configuration to get access to the typed `useParams()` hook.\n\n## Splat / Catch-All Routes\n\nAs expected, splat/catch-all routes also work the same in code-based routing as they do in file-based routing. Simply prefix a segment of the path with a `$` and it will be captured into the `params` object under the `_splat` key:\n\n```tsx\nconst filesRoute = createRoute({\n getParentRoute: () => rootRoute,\n path: 'files',\n})\n\nconst fileRoute = createRoute({\n getParentRoute: () => filesRoute,\n path: '$',\n})\n```\n\nFor the URL `/documents/hello-world`, the `params` object will look like this:\n\n```js\n{\n '_splat': 'documents/hello-world'\n}\n```\n\n## Layout Routes\n\nLayout routes are routes that wrap their children in a layout component. In code-based routing, you can create a layout route by simply nesting a route under another route:\n\n```tsx\nconst postsRoute = createRoute({\n getParentRoute: () => rootRoute,\n path: 'posts',\n component: PostsLayoutComponent, // The layout component\n})\n\nfunction PostsLayoutComponent() {\n return (\n <div>\n <h1>Posts</h1>\n <Outlet />\n </div>\n )\n}\n\nconst postsIndexRoute = createRoute({\n getParentRoute: () => postsRoute,\n path: '/',\n})\n\nconst postsCreateRoute = createRoute({\n getParentRoute: () => postsRoute,\n path: 'create',\n})\n\nconst routeTree = rootRoute.addChildren([\n // The postsRoute is the layout route\n // Its children will be nested under the PostsLayoutComponent\n postsRoute.addChildren([postsIndexRoute, postsCreateRoute]),\n])\n```\n\nNow, both the `postsIndexRoute` and `postsCreateRoute` will render their contents inside of the `PostsLayoutComponent`:\n\n```tsx\n// URL: /posts\n<PostsLayoutComponent>\n <PostsIndexComponent />\n</PostsLayoutComponent>\n\n// URL: /posts/create\n<PostsLayoutComponent>\n <PostsCreateComponent />\n</PostsLayoutComponent>\n```\n\n## Pathless Layout Routes\n\nIn file-based routing a pathless layout route is prefixed with a `_`, but in code-based routing, this is simply a route with an `id` instead of a `path` option. This is because code-based routing does not use the filesystem to organize routes, so there is no need to prefix a route with a `_` to denote that it has no path.\n\n```tsx\nconst pathlessLayoutRoute = createRoute({\n getParentRoute: () => rootRoute,\n id: 'pathlessLayout',\n component: PathlessLayoutComponent,\n})\n\nfunction PathlessLayoutComponent() {\n return (\n <div>\n <h1>Pathless Layout</h1>\n <Outlet />\n </div>\n )\n}\n\nconst pathlessLayoutARoute = createRoute({\n getParentRoute: () => pathlessLayoutRoute,\n path: 'route-a',\n})\n\nconst pathlessLayoutBRoute = createRoute({\n getParentRoute: () => pathlessLayoutRoute,\n path: 'route-b',\n})\n\nconst routeTree = rootRoute.addChildren([\n // The pathless layout route has no path, only an id\n // So its children will be nested under the pathless layout route\n pathlessLayoutRoute.addChildren([pathlessLayoutARoute, pathlessLayoutBRoute]),\n])\n```\n\nNow both `/route-a` and `/route-b` will render their contents inside of the `PathlessLayoutComponent`:\n\n```tsx\n// URL: /route-a\n<PathlessLayoutComponent>\n <RouteAComponent />\n</PathlessLayoutComponent>\n\n// URL: /route-b\n<PathlessLayoutComponent>\n <RouteBComponent />\n</PathlessLayoutComponent>\n```\n\n## Non-Nested Routes\n\nBuilding non-nested routes in code-based routing does not require using a trailing `_` in the path, but does require you to build your route and route tree with the right paths and nesting. Let's consider the route tree where we want the post editor to **not** be nested under the posts route:\n\n- `/posts_/$postId/edit`\n- `/posts`\n - `$postId`\n\nTo do this we need to build a separate route for the post editor and include the entire path in the `path` option from the root of where we want the route to be nested (in this case, the root):\n\n```tsx\n// The posts editor route is nested under the root route\nconst postEditorRoute = createRoute({\n getParentRoute: () => rootRoute,\n // The path includes the entire path we need to match\n path: 'posts/$postId/edit',\n})\n\nconst postsRoute = createRoute({\n getParentRoute: () => rootRoute,\n path: 'posts',\n})\n\nconst postRoute = createRoute({\n getParentRoute: () => postsRoute,\n path: '$postId',\n})\n\nconst routeTree = rootRoute.addChildren([\n // The post editor route is nested under the root route\n postEditorRoute,\n postsRoute.addChildren([postRoute]),\n])\n```\n\n# File-Based Routing\n\nMost of the TanStack Router documentation is written for file-based routing and is intended to help you understand in more detail how to configure file-based routing and the technical details behind how it works. While file-based routing is the preferred and recommended way to configure TanStack Router, you can also use [code-based routing](../code-based-routing.md) if you prefer.\n\n## What is File-Based Routing?\n\nFile-based routing is a way to configure your routes using the filesystem. Instead of defining your route structure via code, you can define your routes using a series of files and directories that represent the route hierarchy of your application. This brings a number of benefits:\n\n- **Simplicity**: File-based routing is visually intuitive and easy to understand for both new and experienced developers.\n- **Organization**: Routes are organized in a way that mirrors the URL structure of your application.\n- **Scalability**: As your application grows, file-based routing makes it easy to add new routes and maintain existing ones.\n- **Code-Splitting**: File-based routing allows TanStack Router to automatically code-split your routes for better performance.\n- **Type-Safety**: File-based routing raises the ceiling on type-safety by generating managing type linkages for your routes, which can otherwise be a tedious process via code-based routing.\n- **Consistency**: File-based routing enforces a consistent structure for your routes, making it easier to maintain and update your application and move from one project to another.\n\n## `/`s or `.`s?\n\nWhile directories have long been used to represent route hierarchy, file-based routing introduces an additional concept of using the `.` character in the file-name to denote a route nesting. This allows you to avoid creating directories for few deeply nested routes and continue to use directories for wider route hierarchies. Let's take a look at some examples!\n\n## Directory Routes\n\nDirectories can be used to denote route hierarchy, which can be useful for organizing multiple routes into logical groups and also cutting down on the filename length for large groups of deeply nested routes.\n\nSee the example below:\n\n| Filename | Route Path | Component Output |\n| ----------------------- | ------------------------- | --------------------------------- |\n| \u02A6 `__root.tsx` | | `<Root>` |\n| \u02A6 `index.tsx` | `/` (exact) | `<Root><RootIndex>` |\n| \u02A6 `about.tsx` | `/about` | `<Root><About>` |\n| \u02A6 `posts.tsx` | `/posts` | `<Root><Posts>` |\n| \uD83D\uDCC2 `posts` | | |\n| \u2504 \u02A6 `index.tsx` | `/posts` (exact) | `<Root><Posts><PostsIndex>` |\n| \u2504 \u02A6 `$postId.tsx` | `/posts/$postId` | `<Root><Posts><Post>` |\n| \uD83D\uDCC2 `posts_` | | |\n| \u2504 \uD83D\uDCC2 `$postId` | | |\n| \u2504 \u2504 \u02A6 `edit.tsx` | `/posts/$postId/edit` | `<Root><EditPost>` |\n| \u02A6 `settings.tsx` | `/settings` | `<Root><Settings>` |\n| \uD83D\uDCC2 `settings` | | `<Root><Settings>` |\n| \u2504 \u02A6 `profile.tsx` | `/settings/profile` | `<Root><Settings><Profile>` |\n| \u2504 \u02A6 `notifications.tsx` | `/settings/notifications` | `<Root><Settings><Notifications>` |\n| \u02A6 `_pathlessLayout.tsx` | | `<Root><PathlessLayout>` |\n| \uD83D\uDCC2 `_pathlessLayout` | | |\n| \u2504 \u02A6 `route-a.tsx` | `/route-a` | `<Root><PathlessLayout><RouteA>` |\n| \u2504 \u02A6 `route-b.tsx` | `/route-b` | `<Root><PathlessLayout><RouteB>` |\n| \uD83D\uDCC2 `files` | | |\n| \u2504 \u02A6 `$.tsx` | `/files/$` | `<Root><Files>` |\n| \uD83D\uDCC2 `account` | | |\n| \u2504 \u02A6 `route.tsx` | `/account` | `<Root><Account>` |\n| \u2504 \u02A6 `overview.tsx` | `/account/overview` | `<Root><Account><Overview>` |\n\n## Flat Routes\n\nFlat routing gives you the ability to use `.`s to denote route nesting levels.\n\nThis can be useful when you have a large number of uniquely deeply nested routes and want to avoid creating directories for each one:\n\nSee the example below:\n\n| Filename | Route Path | Component Output |\n| ------------------------------- | ------------------------- | --------------------------------- |\n| \u02A6 `__root.tsx` | | `<Root>` |\n| \u02A6 `index.tsx` | `/` (exact) | `<Root><RootIndex>` |\n| \u02A6 `about.tsx` | `/about` | `<Root><About>` |\n| \u02A6 `posts.tsx` | `/posts` | `<Root><Posts>` |\n| \u02A6 `posts.index.tsx` | `/posts` (exact) | `<Root><Posts><PostsIndex>` |\n| \u02A6 `posts.$postId.tsx` | `/posts/$postId` | `<Root><Posts><Post>` |\n| \u02A6 `posts_.$postId.edit.tsx` | `/posts/$postId/edit` | `<Root><EditPost>` |\n| \u02A6 `settings.tsx` | `/settings` | `<Root><Settings>` |\n| \u02A6 `settings.profile.tsx` | `/settings/profile` | `<Root><Settings><Profile>` |\n| \u02A6 `settings.notifications.tsx` | `/settings/notifications` | `<Root><Settings><Notifications>` |\n| \u02A6 `_pathlessLayout.tsx` | | `<Root><PathlessLayout>` |\n| \u02A6 `_pathlessLayout.route-a.tsx` | `/route-a` | `<Root><PathlessLayout><RouteA>` |\n| \u02A6 `_pathlessLayout.route-b.tsx` | `/route-b` | `<Root><PathlessLayout><RouteB>` |\n| \u02A6 `files.$.tsx` | `/files/$` | `<Root><Files>` |\n| \u02A6 `account.tsx` | `/account` | `<Root><Account>` |\n| \u02A6 `account.overview.tsx` | `/account/overview` | `<Root><Account><Overview>` |\n\n## Mixed Flat and Directory Routes\n\nIt's extremely likely that a 100% directory or flat route structure won't be the best fit for your project, which is why TanStack Router allows you to mix both flat and directory routes together to create a route tree that uses the best of both worlds where it makes sense:\n\nSee the example below:\n\n| Filename | Route Path | Component Output |\n| ------------------------------ | ------------------------- | --------------------------------- |\n| \u02A6 `__root.tsx` | | `<Root>` |\n| \u02A6 `index.tsx` | `/` (exact) | `<Root><RootIndex>` |\n| \u02A6 `about.tsx` | `/about` | `<Root><About>` |\n| \u02A6 `posts.tsx` | `/posts` | `<Root><Posts>` |\n| \uD83D\uDCC2 `posts` | | |\n| \u2504 \u02A6 `index.tsx` | `/posts` (exact) | `<Root><Posts><PostsIndex>` |\n| \u2504 \u02A6 `$postId.tsx` | `/posts/$postId` | `<Root><Posts><Post>` |\n| \u2504 \u02A6 `$postId.edit.tsx` | `/posts/$postId/edit` | `<Root><Posts><Post><EditPost>` |\n| \u02A6 `settings.tsx` | `/settings` | `<Root><Settings>` |\n| \u02A6 `settings.profile.tsx` | `/settings/profile` | `<Root><Settings><Profile>` |\n| \u02A6 `settings.notifications.tsx` | `/settings/notifications` | `<Root><Settings><Notifications>` |\n| \u02A6 `account.tsx` | `/account` | `<Root><Account>` |\n| \u02A6 `account.overview.tsx` | `/account/overview` | `<Root><Account><Overview>` |\n\nBoth flat and directory routes can be mixed together to create a route tree that uses the best of both worlds where it makes sense.\n\n> [!TIP]\n> If you find that the default file-based routing structure doesn't fit your needs, you can always use [Virtual File Routes](../virtual-file-routes.md) to control the source of your routes whilst still getting the awesome performance benefits of file-based routing.\n\n## Getting started with File-Based Routing\n\nTo get started with file-based routing, you'll need to configure your project's bundler to use the TanStack Router Plugin or the TanStack Router CLI.\n\nTo enable file-based routing, you'll need to be using React with a supported bundler. See if your bundler is listed in the configuration guides below.\n\n[//]: # 'SupportedBundlersList'\n\n- [Installation with Vite](../../installation/with-vite)\n- [Installation with Rspack/Rsbuild](../../installation/with-rspack)\n- [Installation with Webpack](../../installation/with-webpack)\n- [Installation with Esbuild](../../installation/with-esbuild)\n\n[//]: # 'SupportedBundlersList'\n\nWhen using TanStack Router's file-based routing through one of the supported bundlers, our plugin will **automatically generate your route configuration through your bundler's dev and build processes**. It is the easiest way to use TanStack Router's route generation features.\n\nIf your bundler is not yet supported, you can reach out to us on Discord or GitHub to let us know.\n\n# File Naming Conventions\n\nFile-based routing requires that you follow a few simple file naming conventions to ensure that your routes are generated correctly. The concepts these conventions enable are covered in detail in the [Route Trees & Nesting](../route-trees.md) guide.\n\n| Feature | Description |\n| ---------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| **`__root.tsx`** | The root route file must be named `__root.tsx` and must be placed in the root of the configured `routesDirectory`. |\n| **`.` Separator** | Routes can use the `.` character to denote a nested route. For example, `blog.post` will be generated as a child of `blog`. |\n| **`$` Token** | Route segments with the `$` token are parameterized and will extract the value from the URL pathname as a route `param`. |\n| **`_` Prefix** | Route segments with the `_` prefix are considered to be pathless layout routes and will not be used when matching its child routes against the URL pathname. |\n| **`_` Suffix** | Route segments with the `_` suffix exclude the route from being nested under any parent routes. |\n| **`-` Prefix** | Files and folders with the `-` prefix are excluded from the route tree. They will not be added to the `routeTree.gen.ts` file and can be used to colocate logic in route folders. |\n| **`(folder)` folder name pattern** | A folder that matches this pattern is treated as a **route group**, preventing the folder from being included in the route's URL path. |\n| **`[x]` Escaping** | Square brackets escape special characters in filenames that would otherwise have routing meaning. For example, `script[.]js.tsx` becomes `/script.js` and `api[.]v1.tsx` becomes `/api.v1`. |\n| **`index` Token** | Route segments ending with the `index` token (before any file extensions) will match the parent route when the URL pathname matches the parent route exactly. This can be configured via the `indexToken` configuration option, see [options](../../../../api/file-based-routing.md#indextoken). |\n| **`.route.tsx` File Type** | When using directories to organise routes, the `route` suffix can be used to create a route file at the directory's path. For example, `blog.post.route.tsx` or `blog/post/route.tsx` can be used as the route file for the `/blog/post` route. This can be configured via the `routeToken` configuration option, see [options](../../../../api/file-based-routing.md#routetoken). |\n\n> **\uD83D\uDCA1 Remember:** The file-naming conventions for your project could be affected by what [options](../../../../api/file-based-routing.md) are configured.\n\n> [!NOTE]\n> To escape a trailing underscore, for example `/posts[_].tsx`, usage of the upgraded [Non-Nested Routes](../routing-concepts#non-nested-routes) is required.\n\n## Dynamic Path Params\n\nDynamic path params can be used in both flat and directory routes to create routes that can match a dynamic segment of the URL path. Dynamic path params are denoted by the `$` character in the filename:\n\n| Filename | Route Path | Component Output |\n| --------------------- | ---------------- | --------------------- |\n| ... | ... | ... |\n| \u02A6 `posts.$postId.tsx` | `/posts/$postId` | `<Root><Posts><Post>` |\n\nWe'll learn more about dynamic path params in the [Path Params](../../guide/path-params.md) guide.\n\n## Pathless Routes\n\nPathless routes wrap child routes with either logic or a component without requiring a URL path. Non-path routes are denoted by the `_` character in the filename:\n\n| Filename | Route Path | Component Output |\n| -------------- | ---------- | ---------------- |\n| \u02A6 `_app.tsx` | | |\n| \u02A6 `_app.a.tsx` | /a | `<Root><App><A>` |\n| \u02A6 `_app.b.tsx` | /b | `<Root><App><B>` |\n\nTo learn more about pathless routes, see the [Routing Concepts - Pathless Routes](../routing-concepts.md#pathless-layout-routes) guide.\n\n# Route Matching\n\nRoute matching follows a consistent and predictable pattern. This guide will explain how route trees are matched.\n\nWhen TanStack Router processes your route tree, all of your routes are automatically sorted to match the most specific routes first. This means that regardless of the order your route tree is defined, routes will always be sorted in this order:\n\n- Index Route\n- Static Routes (most specific to least specific)\n- Dynamic Routes (longest to shortest)\n- Splat/Wildcard Routes\n\nConsider the following pseudo route tree:\n\n```\nRoot\n - blog\n - $postId\n - /\n - new\n - /\n - *\n - about\n - about/us\n```\n\nAfter sorting, this route tree will become:\n\n```\nRoot\n - /\n - about/us\n - about\n - blog\n - /\n - new\n - $postId\n - *\n```\n\nThis final order represents the order in which routes will be matched based on specificity.\n\nUsing that route tree, let's follow the matching process for a few different URLs:\n\n- `/blog`\n ```\n Root\n \u274C /\n \u274C about/us\n \u274C about\n \u23E9 blog\n \u2705 /\n - new\n - $postId\n - *\n ```\n- `/blog/my-post`\n ```\n Root\n \u274C /\n \u274C about/us\n \u274C about\n \u23E9 blog\n \u274C /\n \u274C new\n \u2705 $postId\n - *\n ```\n- `/`\n ```\n Root\n \u2705 /\n - about/us\n - about\n - blog\n - /\n - new\n - $postId\n - *\n ```\n- `/not-a-route`\n ```\n Root\n \u274C /\n \u274C about/us\n \u274C about\n \u274C blog\n - /\n - new\n - $postId\n \u2705 *\n ```\n\n# Route Trees\n\nTanStack Router uses a nested route tree to match up the URL with the correct component tree to render.\n\nTo build a route tree, TanStack Router supports:\n\n- [File-Based Routing](../file-based-routing.md)\n- [Code-Based Routing](../code-based-routing.md)\n\nBoth methods support the exact same core features and functionality, but **file-based routing requires less code for the same or better results**. For this reason, **file-based routing is the preferred and recommended way** to configure TanStack Router. Most of the documentation is written from the perspective of file-based routing.\n\n## Route Trees\n\nNested routing is a powerful concept that allows you to use a URL to render a nested component tree. For example, given the URL of `/blog/posts/123`, you could create a route hierarchy that looks like this:\n\n```tsx\n\u251C\u2500\u2500 blog\n\u2502 \u251C\u2500\u2500 posts\n\u2502 \u2502 \u251C\u2500\u2500 $postId\n```\n\nAnd render a component tree that looks like this:\n\n```tsx\n<Blog>\n <Posts>\n <Post postId=\"123\" />\n </Posts>\n</Blog>\n```\n\nLet's take that concept and expand it out to a larger site structure, but with file-names now:\n\n```\n/routes\n\u251C\u2500\u2500 __root.tsx\n\u251C\u2500\u2500 index.tsx\n\u251C\u2500\u2500 about.tsx\n\u251C\u2500\u2500 posts/\n\u2502 \u251C\u2500\u2500 index.tsx\n\u2502 \u251C\u2500\u2500 $postId.tsx\n\u251C\u2500\u2500 posts.$postId.edit.tsx\n\u251C\u2500\u2500 settings/\n\u2502 \u251C\u2500\u2500 profile.tsx\n\u2502 \u251C\u2500\u2500 notifications.tsx\n\u251C\u2500\u2500 _pathlessLayout/\n\u2502 \u251C\u2500\u2500 route-a.tsx\n\u251C\u2500\u2500 \u251C\u2500\u2500 route-b.tsx\n\u251C\u2500\u2500 files/\n\u2502 \u251C\u2500\u2500 $.tsx\n```\n\nThe above is a valid route tree configuration that can be used with TanStack Router! There's a lot of power and convention to unpack with file-based routing, so let's break it down a bit.\n\n## Route Tree Configuration\n\nRoute trees can be configured using a few different ways:\n\n- [Flat Routes](../file-based-routing.md#flat-routes)\n- [Directories](../file-based-routing.md#directory-routes)\n- [Mixed Flat Routes and Directories](../file-based-routing.md#mixed-flat-and-directory-routes)\n- [Virtual File Routes](../virtual-file-routes.md)\n- [Code-Based Routes](../code-based-routing.md)\n\nPlease be sure to check out the full documentation links above for each type of route tree, or just proceed to the next section to get started with file-based routing.\n\n# Routing Concepts\n\nTanStack Router supports a number of powerful routing concepts that allow you to build complex and dynamic routing systems with ease.\n\nEach of these concepts is useful and powerful, and we'll dive into each of them in the following sections.\n\n## Anatomy of a Route\n\nAll other routes, other than the [Root Route](#the-root-route), are configured using the `createFileRoute` function, which provides type safety when using file-based routing:\n\n```tsx\nimport { createFileRoute } from '@tanstack/react-router'\n\nexport const Route = createFileRoute('/')({\n component: PostsComponent,\n})\n```\n\nThe `createFileRoute` function takes a single argument, the file-route's path as a string.\n\n**\u2753\u2753\u2753 \"Wait, you're making me pass the path of the route file to `createFileRoute`?\"**\n\nYes! But don't worry, this path is **automatically written and managed by the router for you via the TanStack Router Bundler Plugin or Router CLI.** So, as you create new routes, move routes around or rename routes, the path will be updated for you automatically.\n\nThe reason for this pathname has everything to do with the magical type safety of TanStack Router. Without this pathname, TypeScript would have no idea what file we're in! (We wish TypeScript had a built-in for this, but they don't yet \uD83E\uDD37\u200D\u2642\uFE0F)\n\n## The Root Route\n\nThe root route is the top-most route in the entire tree and encapsulates all other routes as children.\n\n- It has no path\n- It is **always** matched\n- Its `component` is **always** rendered\n\nEven though it doesn't have a path, the root route has access to all of the same functionality as other routes including:\n\n- components\n- loaders\n- search param validation\n- etc.\n\nTo create a root route, call the `createRootRoute()` function and export it as the `Route` variable in your route file:\n\n```tsx\n// Standard root route\nimport { createRootRoute } from '@tanstack/react-router'\n\nexport const Route = createRootRoute()\n\n// Root route with Context\nimport { createRootRouteWithContext } from '@tanstack/react-router'\nimport type { QueryClient } from '@tanstack/react-query'\n\nexport interface MyRouterContext {\n queryClient: QueryClient\n}\nexport const Route = createRootRouteWithContext<MyRouterContext>()\n```\n\nTo learn more about Context in TanStack Router, see the [Router Context](../../guide/router-context.md) guide.\n\n## Basic Routes\n\nBasic routes match a specific path, for example `/about`, `/settings`, `/settings/notifications` are all basic routes, as they match the path exactly.\n\nLet's take a look at an `/about` route:\n\n```tsx\n// about.tsx\nimport { createFileRoute } from '@tanstack/react-router'\n\nexport const Route = createFileRoute('/about')({\n component: AboutComponent,\n})\n\nfunction AboutComponent() {\n return <div>About</div>\n}\n```\n\nBasic routes are simple and straightforward. They match the path exactly and render the provided component.\n\n## Index Routes\n\nIndex routes specifically target their parent route when it is **matched exactly and no child route is matched**.\n\nLet's take a look at an index route for a `/posts` URL:\n\n```tsx\n// posts.index.tsx\nimport { createFileRoute } from '@tanstack/react-router'\n\n// Note the trailing slash, which is used to target index routes\nexport const Route = createFileRoute('/posts/')({\n component: PostsIndexComponent,\n})\n\nfunction PostsIndexComponent() {\n return <div>Please select a post!</div>\n}\n```\n\nThis route will be matched when the URL is `/posts` exactly.\n\n## Dynamic Route Segments\n\nRoute path segments that start with a `$` followed by a label are dynamic and capture that section of the URL into the `params` object for use in your application. For example, a pathname of `/posts/123` would match the `/posts/$postId` route, and the `params` object would be `{ postId: '123' }`.\n\nThese params are then usable in your route's configuration and components! Let's look at a `posts.$postId.tsx` route:\n\n```tsx\nimport { createFileRoute } from '@tanstack/react-router'\n\nexport const Route = createFileRoute('/posts/$postId')({\n // In a loader\n loader: ({ params }) => fetchPost(params.postId),\n // Or in a component\n component: PostComponent,\n})\n\nfunction PostComponent() {\n // In a component!\n const { postId } = Route.useParams()\n return <div>Post ID: {postId}</div>\n}\n```\n\n> \uD83E\uDDE0 Dynamic segments work at **each** segment of the path. For example, you could have a route with the path of `/posts/$postId/$revisionId` and each `$` segment would be captured into the `params` object.\n\n## Splat / Catch-All Routes\n\nA route with a path of only `$` is called a \"splat\" route because it _always_ captures _any_ remaining section of the URL pathname from the `$` to the end. The captured pathname is then available in the `params` object under the special `_splat` property.\n\nFor example, a route targeting the `files/$` path is a splat route. If the URL pathname is `/files/documents/hello-world`, the `params` object would contain `documents/hello-world` under the special `_splat` property:\n\n```js\n{\n '_splat': 'documents/hello-world'\n}\n```\n\n> \u26A0\uFE0F In v1 of the router, splat routes are also denoted with a `*` instead of a `_splat` key for backwards compatibility. This will be removed in v2.\n\n> \uD83E\uDDE0 Why use `$`? Thanks to tools like Remix, we know that despite `*`s being the most common character to represent a wildcard, they do not play nice with filenames or CLI tools, so just like them, we decided to use `$` instead.\n\n## Optional Path Parameters\n\nOptional path parameters allow you to define route segments that may or may not be present in the URL. They use the `{-$paramName}` syntax and provide flexible routing patterns where certain parameters are optional.\n\n```tsx\n// posts.{-$category}.tsx - Optional category parameter\nimport { createFileRoute } from '@tanstack/react-router'\n\nexport const Route = createFileRoute('/posts/{-$category}')({\n component: PostsComponent,\n})\n\nfunction PostsComponent() {\n const { category } = Route.useParams()\n\n return <div>{category ? `Posts in ${category}` : 'All Posts'}</div>\n}\n```\n\nThis route will match both `/posts` (category is `undefined`) and `/posts/tech` (category is `\"tech\"`).\n\nYou can also define multiple optional parameters in a single route:\n\n```tsx\n// posts.{-$category}.{-$slug}.tsx\nexport const Route = createFileRoute('/posts/{-$category}/{-$slug}')({\n component: PostsComponent,\n})\n```\n\nThis route matches `/posts`, `/posts/tech`, and `/posts/tech/hello-world`.\n\n> \uD83E\uDDE0 Routes with optional parameters are ranked lower in priority than exact matches, ensuring that more specific routes like `/posts/featured` are matched before `/posts/{-$category}`.\n\n## Layout Routes\n\nLayout routes are used to wrap child routes with additional components and logic. They are useful for:\n\n- Wrapping child routes with a layout component\n- Enforcing a `loader` requirement before displaying any child routes\n- Validating and providing search params to child routes\n- Providing fallbacks for error components or pending elements to child routes\n- Providing shared context to all child routes\n- And more!\n\nLet's take a look at an example layout route called `app.tsx`:\n\n```\nroutes/\n\u251C\u2500\u2500 app.tsx\n\u251C\u2500\u2500 app.dashboard.tsx\n\u251C\u2500\u2500 app.settings.tsx\n```\n\nIn the tree above, `app.tsx` is a layout route that wraps two child routes, `app.dashboard.tsx` and `app.settings.tsx`.\n\nThis tree structure is used to wrap the child routes with a layout component:\n\n```tsx\nimport { Outlet, createFileRoute } from '@tanstack/react-router'\n\nexport const Route = createFileRoute('/app')({\n component: AppLayoutComponent,\n})\n\nfunction AppLayoutComponent() {\n return (\n <div>\n <h1>App Layout</h1>\n <Outlet />\n </div>\n )\n}\n```\n\nThe following table shows which component(s) will be rendered based on the URL:\n\n| URL Path | Component |\n| ---------------- | ------------------------ |\n| `/app` | `<AppLayout>` |\n| `/app/dashboard` | `<AppLayout><Dashboard>` |\n| `/app/settings` | `<AppLayout><Settings>` |\n\nSince TanStack Router supports mixed flat and directory routes, you can also express your application's routing using layout routes within directories:\n\n```\nroutes/\n\u251C\u2500\u2500 app/\n\u2502 \u251C\u2500\u2500 route.tsx\n\u2502 \u251C\u2500\u2500 dashboard.tsx\n\u2502 \u251C\u2500\u2500 settings.tsx\n```\n\nIn this nested tree, the `app/route.tsx` file is a configuration for the layout route that wraps two child routes, `app/dashboard.tsx` and `app/settings.tsx`.\n\nLayout Routes also let you enforce component and loader logic for Dynamic Route Segments:\n\n```\nroutes/\n\u251C\u2500\u2500 app/users/\n\u2502 \u251C\u2500\u2500 $userId/\n| | \u251C\u2500\u2500 route.tsx\n| | \u251C\u2500\u2500 index.tsx\n| | \u251C\u2500\u2500 edit.tsx\n```\n\n## Pathless Layout Routes\n\nLike [Layout Routes](#layout-routes), Pathless Layout Routes are used to wrap child routes with additional components and logic. However, pathless layout routes do not require a matching `path` in the URL and are used to wrap child routes with additional components and logic without requiring a matching `path` in the URL.\n\nPathless Layout Routes are prefixed with an underscore (`_`) to denote that they are \"pathless\".\n\n> \uD83E\uDDE0 The part of the path after the `_` prefix is used as the route's ID and is required because every route must be uniquely identifiable, especially when using TypeScript so as to avoid type errors and accomplish autocomplete effectively.\n\nLet's take a look at an example route called `_pathlessLayout.tsx`:\n\n```\n\nroutes/\n\u251C\u2500\u2500 _pathlessLayout.tsx\n\u251C\u2500\u2500 _pathlessLayout.a.tsx\n\u251C\u2500\u2500 _pathlessLayout.b.tsx\n\n```\n\nIn the tree above, `_pathlessLayout.tsx` is a pathless layout route that wraps two child routes, `_pathlessLayout.a.tsx` and `_pathlessLayout.b.tsx`.\n\nThe `_pathlessLayout.tsx` route is used to wrap the child routes with a Pathless layout component:\n\n```tsx\nimport { Outlet, createFileRoute } from '@tanstack/react-router'\n\nexport const Route = createFileRoute('/_pathlessLayout')({\n component: PathlessLayoutComponent,\n})\n\nfunction PathlessLayoutComponent() {\n return (\n <div>\n <h1>Pathless layout</h1>\n <Outlet />\n </div>\n )\n}\n```\n\nThe following table shows which component will be rendered based on the URL:\n\n| URL Path | Component |\n| -------- | --------------------- |\n| `/` | `<Index>` |\n| `/a` | `<PathlessLayout><A>` |\n| `/b` | `<PathlessLayout><B>` |\n\nSince TanStack Router supports mixed flat and directory routes, you can also express your application's routing using pathless layout routes within directories:\n\n```\nroutes/\n\u251C\u2500\u2500 _pathlessLayout/\n\u2502 \u251C\u2500\u2500 route.tsx\n\u2502 \u251C\u2500\u2500 a.tsx\n\u2502 \u251C\u2500\u2500 b.tsx\n```\n\nHowever, unlike Layout Routes, since Pathless Layout Routes do match based on URL path segments, this means that these routes do not support [Dynamic Route Segments](#dynamic-route-segments) as part of their path and therefore cannot be matched in the URL.\n\nThis means that you cannot do this:\n\n```\nroutes/\n\u251C\u2500\u2500 _$postId/ \u274C\n\u2502 \u251C\u2500\u2500 ...\n```\n\nRather, you'd have to do this:\n\n```\nroutes/\n\u251C\u2500\u2500 $postId/\n\u251C\u2500\u2500 _postPathlessLayout/ \u2705\n\u2502 \u251C\u2500\u2500 ...\n```\n\n## Non-Nested Routes\n\nNon-nested routes can be created by suffixing a parent file route segment with a `_` and are used to **un-nest** a route from its parents and render its own component tree.\n\nConsider the following flat route tree:\n\n```\nroutes/\n\u251C\u2500\u2500 posts.tsx\n\u251C\u2500\u2500 posts.$postId.tsx\n\u251C\u2500\u2500 posts_.$postId.edit.tsx\n```\n\nThe following table shows which component will be rendered based on the URL:\n\n| URL Path | Component |\n| ----------------- | ---------------------------- |\n| `/posts` | `<Posts>` |\n| `/posts/123` | `<Posts><Post postId=\"123\">` |\n| `/posts/123/edit` | `<PostEditor postId=\"123\">` |\n\n- The `posts.$postId.tsx` route is nested as normal under the `posts.tsx` route and will render `<Posts><Post>`.\n- The `posts_.$postId.edit.tsx` route **does not share** the same `posts` prefix as the other routes and therefore will be treated as if it is a top-level route and will render `<PostEditor>`.\n\n> [!NOTE]\n> While using non-nested routes with file-based routing already works brilliantly, it might misbehave in certain conditions.\n> Many of these limitations have already been addressed and will be released in the next major version of TanStack Router.\n>\n> To start enjoying these benefits early, you can enable the experimental `nonNestedRoutes` flag in the router plugin configuration:\n>\n> ```ts\n> export default defineConfig({\n> plugins: [\n> tanstackRouter({\n> // some config,\n> experimental: {\n> nonNestedRoutes: true,\n> },\n> }),\n> ],\n> })\n> ```\n>\n> _It is important to note that this does bring a slight change in how non-nested routes are referenced in useParams, useNavigate, etc. For this reason this has been released as a feature flag.\n> The trailing underscore is no longer expected in the path:_\n>\n> Previously:\n>\n> ```ts\n> useParams({ from: '/posts_/$postId/edit' })\n> ```\n>\n> Now:\n>\n> ```ts\n> useParams({ from: '/posts/$postId/edit' })\n> ```\n\n## Excluding Files and Folders from Routes\n\nFiles and folders can be excluded from route generation with a `-` prefix attached to the file name. This gives you the ability to colocate logic in the route directories.\n\nConsider the following route tree:\n\n```\nroutes/\n\u251C\u2500\u2500 posts.tsx\n\u251C\u2500\u2500 -posts-table.tsx // \uD83D\uDC48\uD83C\uDFFC ignored\n\u251C\u2500\u2500 -components/ // \uD83D\uDC48\uD83C\uDFFC ignored\n\u2502 \u251C\u2500\u2500 header.tsx // \uD83D\uDC48\uD83C\uDFFC ignored\n\u2502 \u251C\u2500\u2500 footer.tsx // \uD83D\uDC48\uD83C\uDFFC ignored\n\u2502 \u251C\u2500\u2500 ...\n```\n\nWe can import from the excluded files into our posts route\n\n```tsx\nimport { createFileRoute } from '@tanstack/react-router'\nimport { PostsTable } from './-posts-table'\nimport { PostsHeader } from './-components/header'\nimport { PostsFooter } from './-components/footer'\n\nexport const Route = createFileRoute('/posts')({\n loader: () => fetchPosts(),\n component: PostComponent,\n})\n\nfunction PostComponent() {\n const posts = Route.useLoaderData()\n\n return (\n <div>\n <PostsHeader />\n <PostsTable posts={posts} />\n <PostsFooter />\n </div>\n )\n}\n```\n\nThe excluded files will not be added to `routeTree.gen.ts`.\n\n## Pathless Route Group Directories\n\nPathless route group directories use `()` as a way to group routes files together regardless of their path. They are purely organizational and do not affect the route tree or component tree in any way.\n\n```\nroutes/\n\u251C\u2500\u2500 index.tsx\n\u251C\u2500\u2500 (app)/\n\u2502 \u251C\u2500\u2500 dashboard.tsx\n\u2502 \u251C\u2500\u2500 settings.tsx\n\u2502 \u251C\u2500\u2500 users.tsx\n\u251C\u2500\u2500 (auth)/\n\u2502 \u251C\u2500\u2500 login.tsx\n\u2502 \u251C\u2500\u2500 register.tsx\n```\n\nIn the example above, the `app` and `auth` directories are purely organizational and do not affect the route tree or component tree in any way. They are used to group related routes together for easier navigation and organization.\n\nThe following table shows which component will be rendered based on the URL:\n\n| URL Path | Component |\n| ------------ | ------------- |\n| `/` | `<Index>` |\n| `/dashboard` | `<Dashboard>` |\n| `/settings` | `<Settings>` |\n| `/users` | `<Users>` |\n| `/login` | `<Login>` |\n| `/register` | `<Register>` |\n\nAs you can see, the `app` and `auth` directories are purely organizational and do not affect the route tree or component tree in any way.\n\n# Virtual File Routes\n\n> We'd like to thank the Remix team for [pioneering the concept of virtual file routes](https://www.youtube.com/watch?v=fjTX8hQTlEc&t=730s). We've taken inspiration from their work and adapted it to work with TanStack Router's existing file-based route-tree generation.\n\nVirtual file routes are a powerful concept that allows you to build a route tree programmatically using code that references real files in your project. This can be useful if:\n\n- You have an existing route organization that you want to keep.\n- You want to customize the location of your route files.\n- You want to completely override TanStack Router's file-based route generation and build your own convention.\n\nHere's a quick example of using virtual file routes to map a route tree to a set of real files in your project:\n\n```tsx\n// routes.ts\nimport {\n rootRoute,\n route,\n index,\n layout,\n physical,\n} from '@tanstack/virtual-file-routes'\n\nexport const routes = rootRoute('root.tsx', [\n index('index.tsx'),\n layout('pathlessLayout.tsx', [\n route('/dashboard', 'app/dashboard.tsx', [\n index('app/dashboard-index.tsx'),\n route('/invoices', 'app/dashboard-invoices.tsx', [\n index('app/invoices-index.tsx'),\n route('$id', 'app/invoice-detail.tsx'),\n ]),\n ]),\n physical('/posts', 'posts'),\n ]),\n])\n```\n\n## Configuration\n\nVirtual file routes can be configured either via:\n\n- The `TanStackRouter` plugin for Vite/Rspack/Webpack\n- The `tsr.config.json` file for the TanStack Router CLI\n\n## Configuration via the TanStackRouter Plugin\n\nIf you're using the `TanStackRouter` plugin for Vite/Rspack/Webpack, you can configure virtual file routes by passing the path of your routes file to the `virtualRoutesConfig` option when setting up the plugin:\n\n```tsx\n// vite.config.ts\nimport { defineConfig } from 'vite'\nimport react from '@vitejs/plugin-react'\nimport { tanstackRouter } from '@tanstack/router-plugin/vite'\n\nexport default defineConfig({\n plugins: [\n tanstackRouter({\n target: 'react',\n virtualRouteConfig: './routes.ts',\n }),\n react(),\n ],\n})\n```\n\nOr, you choose to define the virtual routes directly in the configuration:\n\n```tsx\n// vite.config.ts\nimport { defineConfig } from 'vite'\nimport react from '@vitejs/plugin-react'\nimport { tanstackRouter } from '@tanstack/router-plugin/vite'\nimport { rootRoute } from '@tanstack/virtual-file-routes'\n\nconst routes = rootRoute('root.tsx', [\n // ... the rest of your virtual route tree\n])\n\nexport default defineConfig({\n plugins: [tanstackRouter({ virtualRouteConfig: routes }), react()],\n})\n```\n\n## Creating Virtual File Routes\n\nTo create virtual file routes, you'll need to import the `@tanstack/virtual-file-routes` package. This package provides a set of functions that allow you to create virtual routes that reference real files in your project. A few utility functions are exported from the package:\n\n- `rootRoute` - Creates a virtual root route.\n- `route` - Creates a virtual route.\n- `index` - Creates a virtual index route.\n- `layout` - Creates a virtual pathless layout route.\n- `physical` - Creates a physical virtual route (more on this later).\n\n## Virtual Root Route\n\nThe `rootRoute` function is used to create a virtual root route. It takes a file name and an array of children routes. Here's an example of a virtual root route:\n\n```tsx\n// routes.ts\nimport { rootRoute } from '@tanstack/virtual-file-routes'\n\nexport const routes = rootRoute('root.tsx', [\n // ... children routes\n])\n```\n\n## Virtual Route\n\nThe `route` function is used to create a virtual route. It takes a path, a file name, and an array of children routes. Here's an example of a virtual route:\n\n```tsx\n// routes.ts\nimport { route } from '@tanstack/virtual-file-routes'\n\nexport const routes = rootRoute('root.tsx', [\n route('/about', 'about.tsx', [\n // ... children routes\n ]),\n])\n```\n\nYou can also define a virtual route without a file name. This allows to set a common path prefix for its children:\n\n```tsx\n// routes.ts\nimport { route } from '@tanstack/virtual-file-routes'\n\nexport const routes = rootRoute('root.tsx', [\n route('/hello', [\n route('/world', 'world.tsx'), // full path will be \"/hello/world\"\n route('/universe', 'universe.tsx'), // full path will be \"/hello/universe\"\n ]),\n])\n```\n\n## Virtual Index Route\n\nThe `index` function is used to create a virtual index route. It takes a file name. Here's an example of a virtual index route:\n\n```tsx\nimport { index } from '@tanstack/virtual-file-routes'\n\nconst routes = rootRoute('root.tsx', [index('index.tsx')])\n```\n\n## Virtual Pathless Route\n\nThe `layout` function is used to create a virtual pathless route. It takes a file name, an array of children routes, and an optional pathless ID. Here's an example of a virtual pathless route:\n\n```tsx\n// routes.ts\nimport { layout } from '@tanstack/virtual-file-routes'\n\nexport const routes = rootRoute('root.tsx', [\n layout('pathlessLayout.tsx', [\n // ... children routes\n ]),\n])\n```\n\nYou can also specify a pathless ID to give the route a unique identifier that is different from the filename:\n\n```tsx\n// routes.ts\nimport { layout } from '@tanstack/virtual-file-routes'\n\nexport const routes = rootRoute('root.tsx', [\n layout('my-pathless-layout-id', 'pathlessLayout.tsx', [\n // ... children routes\n ]),\n])\n```\n\n## Physical Virtual Routes\n\nPhysical virtual routes are a way to \"mount\" a directory of good ol' TanStack Router File Based routing convention under a specific URL path. This can be useful if you are using virtual routes to customize a small portion of your route tree high up in the hierarchy, but want to use the standard file-based routing convention for sub-routes and directories.\n\nConsider the following file structure:\n\n```\n/routes\n\u251C\u2500\u2500 root.tsx\n\u251C\u2500\u2500 index.tsx\n\u251C\u2500\u2500 pathlessLayout.tsx\n\u251C\u2500\u2500 app\n\u2502 \u251C\u2500\u2500 dashboard.tsx\n\u2502 \u251C\u2500\u2500 dashboard-index.tsx\n\u2502 \u251C\u2500\u2500 dashboard-invoices.tsx\n\u2502 \u251C\u2500\u2500 invoices-index.tsx\n\u2502 \u251C\u2500\u2500 invoice-detail.tsx\n\u2514\u2500\u2500 posts\n \u251C\u2500\u2500 index.tsx\n \u251C\u2500\u2500 $postId.tsx\n \u251C\u2500\u2500 $postId.edit.tsx\n \u251C\u2500\u2500 comments/\n \u2502 \u251C\u2500\u2500 index.tsx\n \u2502 \u251C\u2500\u2500 $commentId.tsx\n \u2514\u2500\u2500 likes/\n \u251C\u2500\u2500 index.tsx\n \u251C\u2500\u2500 $likeId.tsx\n```\n\nLet's use virtual routes to customize our route tree for everything but `posts`, then use physical virtual routes to mount the `posts` directory under the `/posts` path:\n\n```tsx\n// routes.ts\nexport const routes = rootRoute('root.tsx', [\n // Set up your virtual routes as normal\n index('index.tsx'),\n layout('pathlessLayout.tsx', [\n route('/dashboard', 'app/dashboard.tsx', [\n index('app/dashboard-index.tsx'),\n route('/invoices', 'app/dashboard-invoices.tsx', [\n index('app/invoices-index.tsx'),\n route('$id', 'app/invoice-detail.tsx'),\n ]),\n ]),\n // Mount the `posts` directory under the `/posts` path\n physical('/posts', 'posts'),\n ]),\n])\n```\n\n## Virtual Routes inside of TanStack Router File Based routing\n\nThe previous section showed you how you can use TanStack Router's File Based routing convention inside of a virtual route configuration.\nHowever, the opposite is possible as well. \nYou can configure the main part of your app's route tree using TanStack Router's File Based routing convention and opt into virtual route configuration for specific subtrees.\n\nConsider the following file structure:\n\n```\n/routes\n\u251C\u2500\u2500 __root.tsx\n\u251C\u2500\u2500 foo\n\u2502 \u251C\u2500\u2500 bar\n\u2502 \u2502 \u251C\u2500\u2500 __virtual.ts\n\u2502 \u2502 \u251C\u2500\u2500 details.tsx\n\u2502 \u2502 \u251C\u2500\u2500 home.tsx\n\u2502 \u2502 \u2514\u2500\u2500 route.ts\n\u2502 \u2514\u2500\u2500 bar.tsx\n\u2514\u2500\u2500 index.tsx\n```\n\nLet's look at the `bar` directory which contains a special file named `__virtual.ts`. This file instructs the generator to switch over to virtual file route configuration for this directory (and its child directories).\n\n`__virtual.ts` configures the virtual routes for that particular subtree of the route tree. It uses the same API as explained above, with the only difference being that no `rootRoute` is defined for that subtree:\n\n```tsx\n// routes/foo/bar/__virtual.ts\nimport {\n defineVirtualSubtreeConfig,\n index,\n route,\n} from '@tanstack/virtual-file-routes'\n\nexport default defineVirtualSubtreeConfig([\n index('home.tsx'),\n route('$id', 'details.tsx'),\n])\n```\n\nThe helper function `defineVirtualSubtreeConfig` is closely modeled after vite's `defineConfig` and allows you to define a subtree configuration via a default export. The default export can either be\n\n- a subtree config object\n- a function returning a subtree config object\n- an async function returning a subtree config object\n\n## Inception\n\nYou can mix and match TanStack Router's File Based routing convention and virtual route configuration however you like. \nLet's go deeper! \nCheck out the following example that starts off using File Based routing convention, switches over to virtual route configuration for `/posts`, switches back to File Based routing convention for `/posts/lets-go` only to switch over to virtual route configuration again for `/posts/lets-go/deeper`.\n\n```\n\u251C\u2500\u2500 __root.tsx\n\u251C\u2500\u2500 index.tsx\n\u251C\u2500\u2500 posts\n\u2502 \u251C\u2500\u2500 __virtual.ts\n\u2502 \u251C\u2500\u2500 details.tsx\n\u2502 \u251C\u2500\u2500 home.tsx\n\u2502 \u2514\u2500\u2500 lets-go\n\u2502 \u251C\u2500\u2500 deeper\n\u2502 \u2502 \u251C\u2500\u2500 __virtual.ts\n\u2502 \u2502 \u2514\u2500\u2500 home.tsx\n\u2502 \u2514\u2500\u2500 index.tsx\n\u2514\u2500\u2500 posts.tsx\n```\n\n## Configuration via the TanStack Router CLI\n\nIf you're using the TanStack Router CLI, you can configure virtual file routes by defining the path to your routes file in the `tsr.config.json` file:\n\n```json\n// tsr.config.json\n{\n \"virtualRouteConfig\": \"./routes.ts\"\n}\n```\n\nOr you can define the virtual routes directly in the configuration, while much less common allows you to configure them via the TanStack Router CLI by adding a `virtualRouteConfig` object to your `tsr.config.json` file and defining your virtual routes and passing the resulting JSON that is generated by calling the actual `rootRoute`/`route`/`index`/etc functions from the `@tanstack/virtual-file-routes` package:\n\n```json\n// tsr.config.json\n{\n \"virtualRouteConfig\": {\n \"type\": \"root\",\n \"file\": \"root.tsx\",\n \"children\": [\n {\n \"type\": \"index\",\n \"file\": \"home.tsx\"\n },\n {\n \"type\": \"route\",\n \"file\": \"posts/posts.tsx\",\n \"path\": \"/posts\",\n \"children\": [\n {\n \"type\": \"index\",\n \"file\": \"posts/posts-home.tsx\"\n },\n {\n \"type\": \"route\",\n \"file\": \"posts/posts-detail.tsx\",\n \"path\": \"$postId\"\n }\n ]\n },\n {\n \"type\": \"layout\",\n \"id\": \"first\",\n \"file\": \"layout/first-pathless-layout.tsx\",\n \"children\": [\n {\n \"type\": \"layout\",\n \"id\": \"second\",\n \"file\": \"layout/second-pathless-layout.tsx\",\n \"children\": [\n {\n \"type\": \"route\",\n \"file\": \"a.tsx\",\n \"path\": \"/route-a\"\n },\n {\n \"type\": \"route\",\n \"file\": \"b.tsx\",\n \"path\": \"/route-b\"\n }\n ]\n }\n ]\n }\n ]\n }\n}\n```\n\n";
2
2
  export default _default;
@@ -573,7 +573,8 @@ File-based routing requires that you follow a few simple file naming conventions
573
573
 
574
574
  > **💡 Remember:** The file-naming conventions for your project could be affected by what [options](../../../../api/file-based-routing.md) are configured.
575
575
 
576
- > [!NOTE] To escape a trailing underscore, for example \`/posts[_].tsx\`, usage of the upgraded [Non-Nested Routes](../routing-concepts#non-nested-routes) is required.
576
+ > [!NOTE]
577
+ > To escape a trailing underscore, for example \`/posts[_].tsx\`, usage of the upgraded [Non-Nested Routes](../routing-concepts#non-nested-routes) is required.
577
578
 
578
579
  ## Dynamic Path Params
579
580
 
@@ -1,2 +1,2 @@
1
- declare const _default: "# Overview\n\n**TanStack Router is a router for building React and Solid applications**. Some of its features include:\n\n- 100% inferred TypeScript support\n- Typesafe navigation\n- Nested Routing and layout routes (with pathless layouts)\n- Built-in Route Loaders w/ SWR Caching\n- Designed for client-side data caches (TanStack Query, SWR, etc.)\n- Automatic route prefetching\n- Asynchronous route elements and error boundaries\n- File-based Route Generation\n- Typesafe JSON-first Search Params state management APIs\n- Path and Search Parameter Schema Validation\n- Search Param Navigation APIs\n- Custom Search Param parser/serializer support\n- Search param middleware\n- Route matching/loading middleware\n\nTo get started quickly, head to the next page. For a more lengthy explanation, buckle up while I bring you up to speed!\n\n## \"A Fork in the Route\"\n\nUsing a router to build applications is widely regarded as a must-have and is usually one of the first choices you\u2019ll make in your tech stack.\n\n## Why TanStack Router?\n\nTanStack Router delivers on the same fundamental expectations as other routers that you\u2019ve come to expect:\n\n- Nested routes, layout routes, grouped routes\n- File-based Routing\n- Parallel data loading\n- Prefetching\n- URL Path Params\n- Error Boundaries and Handling\n- SSR\n- Route Masking\n\nAnd it also delivers some new features that raise the bar:\n\n- 100% inferred TypeScript support\n- Typesafe navigation\n- Built-in SWR Caching for loaders\n- Designed for client-side data caches (TanStack Query, SWR, etc.)\n- Typesafe JSON-first Search Params state management APIs\n- Path and Search Parameter Schema Validation\n- Search Parameter Navigation APIs\n- Custom Search Param parser/serializer support\n- Search param middleware\n- Inherited Route Context\n- Mixed file-based and code-based routing\n\nLet\u2019s dive into some of the more important ones in more detail!\n\n## 100% Inferred TypeScript Support\n\nEverything these days is written \u201Cin Typescript\u201D or at the very least offers type definitions that are veneered over runtime functionality, but too few packages in the ecosystem actually design their APIs with TypeScript in mind. So while I\u2019m pleased that your router is auto-completing your option fields and catching a few property/method typos here and there, there is much more to be had.\n\n- TanStack Router is fully aware of all of your routes and their configuration at any given point in your code. This includes the path, path params, search params, context, and any other configuration you\u2019ve provided. Ultimately this means that you can navigate to any route in your app with 100% type safety and confidence that your link or navigate call will succeed.\n- TanStack Router provides lossless type-inference. It uses countless generic type parameters to enforce and propagate any type information you give it throughout the rest of its API and ultimately your app. No other router offers this level of type safety and developer confidence.\n\nWhat does all of that mean for you?\n\n- Faster feature development with auto-completion and type hints\n- Safer and faster refactors\n- Confidence that your code will work as expected\n\n## 1st Class Search Parameters\n\nSearch parameters are often an afterthought, treated like a black box of strings (or string) that you can parse and update, but not much else. Existing solutions are **not** type-safe either, adding to the caution that is required to deal with them. Even the most \"modern\" frameworks and routers leave it up to you to figure out how to manage this state. Sometimes they'll parse the search string into an object for you, or sometimes you're left to do it yourself with `URLSearchParams`.\n\nLet's step back and remember that **search params are the most powerful state manager in your entire application.** They are global, serializable, bookmarkable, and shareable making them the perfect place to store any kind of state that needs to survive a page refresh or a social share.\n\nTo live up to that responsibility, search parameters are a first-class citizen in TanStack Router. While still based on standard URLSearchParams, TanStack Router uses a powerful parser/serializer to manage deeper and more complex data structures in your search params, all while keeping them type-safe and easy to work with.\n\n**It's like having `useState` right in the URL!**\n\nSearch parameters are:\n\n- Automatically parsed and serialized as JSON\n- Validated and typed\n- Inherited from parent routes\n- Accessible in loaders, components, and hooks\n- Easily modified with the useSearch hook, Link, navigate, and router.navigate APIs\n- Customizable with a custom search filters and middleware\n- Subscribed via fine-grained search param selectors for efficient re-renders\n\nOnce you start using TanStack Router's search parameters, you'll wonder how you ever lived without them.\n\n## Built-In Caching and Friendly Data Loading\n\nData loading is a critical part of any application and while most existing routers offer some form of critical data loading APIs, they often fall short when it comes to caching and data lifecycle management. Existing solutions suffer from a few common problems:\n\n- No caching at all. Data is always fresh, but your users are left waiting for frequently accessed data to load over and over again.\n- Overly-aggressive caching. Data is cached for too long, leading to stale data and a poor user experience.\n- Blunt invalidation strategies and APIs. Data may be invalidated too often, leading to unnecessary network requests and wasted resources, or you may not have any fine-grained control over when data is invalidated at all.\n\nTanStack Router solves these problems with a two-prong approach to caching and data loading:\n\n### Built-in Cache\n\nTanStack Router provides a light-weight built-in caching layer that works seamlessly with the Router. This caching layer is loosely based on TanStack Query, but with fewer features and a much smaller API surface area. Like TanStack Query, sane but powerful defaults guarantee that your data is cached for reuse, invalidated when necessary, and garbage collected when not in use. It also provides a simple API for invalidating the cache manually when needed.\n\n### Flexible & Powerful Data Lifecycle APIs\n\nTanStack Router is designed with a flexible and powerful data loading API that more easily integrates with existing data fetching libraries like TanStack Query, SWR, Apollo, Relay, or even your own custom data fetching solution. Configurable APIs like `context`, `beforeLoad`, `loaderDeps` and `loader` work in unison to make it easy to define declarative data dependencies, prefetch data, and manage the lifecycle of an external data source with ease.\n\n## Inherited Route Context\n\nTanStack Router's router and route context is a powerful feature that allows you to define context that is specific to a route which is then inherited by all child routes. Even the router and root routes themselves can provide context. Context can be built up both synchronously and asynchronously, and can be used to share data, configuration, or even functions between routes and route configurations. This is especially useful for scenarios like:\n\n- Authentication and Authorization\n- Hybrid SSR/CSR data fetching and preloading\n- Theming\n- Singletons and global utilities\n- Curried or partial application across preloading, loading, and rendering stages\n\nAlso, what would route context be if it weren't type-safe? TanStack Router's route context is fully type-safe and inferred at zero cost to you.\n\n## File-based and/or Code-Based Routing\n\nTanStack Router supports both file-based and code-based routing at the same time. This flexibility allows you to choose the approach that best fits your project's needs.\n\nTanStack Router's file-based routing approach is uniquely user-facing. Route configuration is generated for you either by the Vite plugin or TanStack Router CLI, leaving the usage of said generated code up to you! This means that you're always in total control of your routes and router, even if you use file-based routing.\n\n## Acknowledgements\n\nTanStack Router builds on concepts and patterns popularized by many other OSS projects, including:\n\n- [TRPC](https://trpc.io/)\n- [Remix](https://remix.run)\n- [Chicane](https://swan-io.github.io/chicane/)\n- [Next.js](https://nextjs.org)\n\nWe acknowledge the investment, risk and research that went into their development, but are excited to push the bar they have set even higher.\n\n## Let's go!\n\nEnough overview, there's so much more to do with TanStack Router. Hit that next button and let's get started!\n\n# Quick Start\n\nTanStack Router can be quickly added to any existing React project or used to scaffold a new one.\n\n## TanStack Router Installation\n\n### Requirements\n\nBefore installing TanStack router, please ensure your project meets the following requirements:\n\n[//]: # 'Requirements'\n\n- `react` v18 or later with `createRoot` support.\n- `react-dom` v18 or later.\n\n[//]: # 'Requirements'\n\n> [!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.\n\nTanStack 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).\n\n### Download and Install\n\nTo install TanStack Router in your project, run the following command using your preferred package manager:\n\n[//]: # 'installCommand'\n\n```sh\nnpm install @tanstack/react-router\n# or\npnpm add @tanstack/react-router\n#or\nyarn add @tanstack/react-router\n# or\nbun add @tanstack/react-router\n# or\ndeno add npm:@tanstack/react-router\n```\n\n[//]: # 'installCommand'\n\nOnce installed, you can verify the installation by checking your `package.json` file for the dependency.\n\n[//]: # 'packageJson'\n\n```json\n{\n \"dependencies\": {\n \"@tanstack/react-router\": \"^x.x.x\"\n }\n}\n```\n\n[//]: # 'packageJson'\n\n## New Project Setup\n\nTo 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.\n\n> [!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).\n\nTo create a new project, run the following command in your terminal:\n\n[//]: # 'createAppCommand'\n\n```sh\nnpx create-tsrouter-app@latest\n```\n\n[//]: # 'createAppCommand'\n\nThe CLI will guide you through a short series of prompts to customize your setup, including options for:\n\n[//]: # 'CLIPrompts'\n\n- File-based or code-based route configuration\n- TypeScript support\n- Tailwind CSS integration\n- Toolchain setup\n- Git initialization\n\n[//]: # 'CLIPrompts'\n\nOnce 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:\n\n```sh\ncd your-project-name\nnpm run dev\n```\n\n### Routing Options\n\nTanStack Router supports both file-based and code-based route configurations, allowing you to choose the approach that best fits your workflow.\n\n#### File-Based Route Generation\n\nThe 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.\n\nTo create a new project using file-based route generation, run the following command:\n\n[//]: # 'createAppCommandFileBased'\n\n```sh\nnpx create-tsrouter-app@latest my-app --template file-router\n```\n\n[//]: # 'createAppCommandFileBased'\n\nThis 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:\n\n```sh\ncd my-app\nnpm run dev\n```\n\n#### Code-Based Route Configuration\n\nIf 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.\n\n[//]: # 'createAppCommandCodeBased'\n\n```sh\nnpx create-tsrouter-app@latest my-app\n```\n\n[//]: # 'createAppCommandCodeBased'\n\nSimilar 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:\n\n```sh\ncd my-app\nnpm run dev\n```\n\nWith either approach, you can now start building your React application with TanStack Router!\n\n# Decisions on Developer Experience\n\nWhen people first start using TanStack Router, they often have a lot of questions that revolve around the following themes:\n\n> Why do I have to do things this way?\n\n> Why is it done this way? and not that way?\n\n> I'm used to doing it this way, why should I change?\n\nAnd 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.\n\nBut 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.\n\n## TanStack Router's origin story\n\nIt'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.\n\nAnd 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.\n\n## How does TanStack Router achieve this?\n\n> TypeScript! TypeScript! TypeScript!\n\nEvery 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.\n\nBut to achieve this, we had to make some decisions that deviate from the norms in the routing world.\n\n1. [**Route configuration boilerplate?**](#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.\n2. [**TypeScript module declaration for the router?**](#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.\n3. [**Why push for file-based routing over code-based?**](#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.\n\n> 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.\n\n## Why is the Router's configuration done this way?\n\nWhen 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.\n\nThis 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.\n\n> Can I use JSX to define my routes?\n\nUsing 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.\n\n```tsx\n// \u26D4\uFE0F This is not possible\nfunction App() {\n return (\n <Router>\n <Route path=\"/posts\" component={PostsPage} />\n <Route path=\"/posts/$postId\" component={PostIdPage} />\n {/* ... */}\n </Router>\n // ^? TypeScript cannot infer the routes in this configuration\n )\n}\n```\n\nAnd 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.\n\n> Maybe I could define my routes as a tree of nested objects?\n\n```tsx\n// \u26D4\uFE0F This file will just keep growing and growing...\nconst router = createRouter({\n routes: {\n posts: {\n component: PostsPage, // /posts\n children: {\n $postId: {\n component: PostIdPage, // /posts/$postId\n },\n },\n },\n // ...\n },\n})\n```\n\nAt 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:\n\n- **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.\n- **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.\n\nThis only gets worse as you begin to use more features of the router, such as nested context, loaders, search param validation, etc.\n\n> So, what's the best way to define my routes?\n\nWhat 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.\n\nYou can read more about [code-based routing](../routing/code-based-routing.md) to see how to define your routes in this way.\n\n> [!TIP]\n> Finding Code-based routing to be a bit too cumbersome? See why [file-based routing](#why-is-file-based-routing-the-preferred-way-to-define-routes) is the preferred way to define your routes.\n\n## Declaring the Router instance for type inference\n\n> Why do I have to declare the `Router`?\n\n> This declaration stuff is way too complicated for me...\n\nOnce 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.\n\nThere were two approaches we considered for this:\n\n1. **Imports**: You could import the `Router` instance from the file where you created it and use it directly in your components.\n\n```tsx\nimport { router } from '@/src/app'\nexport const PostsIdLink = () => {\n return (\n <Link<typeof router> to=\"/posts/$postId\" params={{ postId: '123' }}>\n Go to post 123\n </Link>\n )\n}\n```\n\nA 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.\n\n2. **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.\n\nYou'll do this once in your application.\n\n```tsx\n// src/app.tsx\ndeclare module '@tanstack/react-router' {\n interface Register {\n router: typeof router\n }\n}\n```\n\nAnd then you can benefit from its auto-complete anywhere in your app without having to import it.\n\n```tsx\nexport const PostsIdLink = () => {\n return (\n <Link\n to=\"/posts/$postId\"\n // ^? TypeScript will auto-complete this for you\n params={{ postId: '123' }} // and this too!\n >\n Go to post 123\n </Link>\n )\n}\n```\n\nWe 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.\n\n## Why is file-based routing the preferred way to define routes?\n\n> Why are the docs pushing for file-based routing?\n\n> I'm used to defining my routes in a single file, why should I change?\n\nSomething 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.\n\n> [!TIP]\n> 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).\n\nAs 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.\n\nA 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.\n\n```tsx\nimport { createRoute } from '@tanstack/react-router'\nimport { postsRoute } from './postsRoute'\n\nexport const postsIndexRoute = createRoute({\n getParentRoute: () => postsRoute,\n path: '/',\n})\n```\n\nAt 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.\n\nAs such, this is a critical part of the route configuration and a point of failure if not done correctly.\n\nBut 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.\n\n> \uD83E\uDD2F If this route-tree were in its own file for an application with ~40-50 routes, it can easily grow up to 700+ lines.\n\n```tsx\nconst routeTree = rootRoute.addChildren([\n postsRoute.addChildren([postsIndexRoute, postsIdRoute]),\n])\n```\n\nThis 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.\n\nFinally, 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.\n\n```tsx\nimport { createRoute, lazyRouteComponent } from '@tanstack/react-router'\nimport { postsRoute } from './postsRoute'\n\nexport const postsIndexRoute = createRoute({\n getParentRoute: () => postsRoute,\n path: '/',\n component: lazyRouteComponent(() => import('../page-components/posts/index')),\n})\n```\n\nAll 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.\n\n... 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 \uD83E\uDD15.\n\n> So, why's file-based routing the preferred way?\n\nTanStack 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.\n\nThe 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:\n\n1. **Route configuration boilerplate**: It generates the boilerplate for your route configurations.\n2. **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.\n3. **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.\n\nLet's take a look at how the route configuration for the previous example would look like with file-based routing.\n\n```tsx\n// src/routes/posts/index.ts\nimport { createFileRoute } from '@tanstack/react-router'\n\nexport const Route = createFileRoute('/posts/')({\n component: () => 'Posts index component goes here!!!',\n})\n```\n\nThat'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.\n\nAt 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.\n\nCheck 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.\n\n# Devtools\n\n> Link, take this sword... I mean Devtools!... to help you on your way!\n\nWave your hands in the air and shout hooray because TanStack Router comes with dedicated devtools! \uD83E\uDD73\n\nWhen you begin your TanStack Router journey, you'll want these devtools by your side. They help visualize all of the inner workings of TanStack Router and will likely save you hours of debugging if you find yourself in a pinch!\n\n## Installation\n\nThe devtools are a separate package that you need to install:\n\n```sh\nnpm install @tanstack/react-router-devtools\n```\n\nor\n\n```sh\npnpm add @tanstack/react-router-devtools\n```\n\nor\n\n```sh\nyarn add @tanstack/react-router-devtools\n```\n\nor\n\n```sh\nbun add @tanstack/react-router-devtools\n```\n\n## Import the Devtools\n\n```js\nimport { TanStackRouterDevtools } from '@tanstack/react-router-devtools'\n```\n\n## Using Devtools in production\n\nThe Devtools, if imported as `TanStackRouterDevtools` will not be shown in production. If you want to have devtools in an environment with `process.env.NODE_ENV === 'production'`, use instead `TanStackRouterDevtoolsInProd`, which has all the same options:\n\n```tsx\nimport { TanStackRouterDevtoolsInProd } from '@tanstack/react-router-devtools'\n```\n\n## Using inside of the `RouterProvider`\n\nThe easiest way for the devtools to work is to render them inside of your root route (or any other route). This will automatically connect the devtools to the router instance.\n\n```tsx\nconst rootRoute = createRootRoute({\n component: () => (\n <>\n <Outlet />\n <TanStackRouterDevtools />\n </>\n ),\n})\n\nconst routeTree = rootRoute.addChildren([\n // ... other routes\n])\n\nconst router = createRouter({\n routeTree,\n})\n\nfunction App() {\n return <RouterProvider router={router} />\n}\n```\n\n## Manually passing the Router Instance\n\nIf rendering the devtools inside of the `RouterProvider` isn't your cup of tea, a `router` prop for the devtools accepts the same `router` instance you pass to the `Router` component. This makes it possible to place the devtools anywhere on the page, not just inside the provider:\n\n```tsx\nfunction App() {\n return (\n <>\n <RouterProvider router={router} />\n <TanStackRouterDevtools router={router} />\n </>\n )\n}\n```\n\n## Floating Mode\n\nFloating Mode will mount the devtools as a fixed, floating element in your app and provide a toggle in the corner of the screen to show and hide the devtools. This toggle state will be stored and remembered in localStorage across reloads.\n\nPlace the following code as high in your React app as you can. The closer it is to the root of the page, the better it will work!\n\n```js\nimport { TanStackRouterDevtools } from '@tanstack/react-router-devtools'\n\nfunction App() {\n return (\n <>\n <Router />\n <TanStackRouterDevtools initialIsOpen={false} />\n </>\n )\n}\n```\n\n### Devtools Options\n\n- `router: Router`\n - The router instance to connect to.\n- `initialIsOpen: Boolean`\n - Set this `true` if you want the devtools to default to being open.\n- `panelProps: PropsObject`\n - Use this to add props to the panel. For example, you can add `className`, `style` (merge and override default style), etc.\n- `closeButtonProps: PropsObject`\n - Use this to add props to the close button. For example, you can add `className`, `style` (merge and override default style), `onClick` (extend default handler), etc.\n- `toggleButtonProps: PropsObject`\n - Use this to add props to the toggle button. For example, you can add `className`, `style` (merge and override default style), `onClick` (extend default handler), etc.\n- `position?: \"top-left\" | \"top-right\" | \"bottom-left\" | \"bottom-right\"`\n - Defaults to `bottom-left`.\n - The position of the TanStack Router logo to open and close the devtools panel.\n- `shadowDOMTarget?: ShadowRoot`\n - Specifies a Shadow DOM target for the devtools.\n - 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.\n- `containerElement?: string | any`\n - Use this to render the devtools inside a different type of container element for ally purposes.\n - Any string which corresponds to a valid intrinsic JSX element is allowed.\n - Defaults to 'footer'.\n\n## Fixed Mode\n\nTo control the position of the devtools, import the `TanStackRouterDevtoolsPanel`:\n\n```js\nimport { TanStackRouterDevtoolsPanel } from '@tanstack/react-router-devtools'\n```\n\nIt can then be attached to provided shadow DOM target:\n\n```js\n<TanStackRouterDevtoolsPanel\n shadowDOMTarget={shadowContainer}\n router={router}\n/>\n```\n\nClick [here](https://tanstack.com/router/latest/docs/framework/react/examples/basic-devtools-panel) to see a live example of this in StackBlitz.\n\n## Embedded Mode\n\nEmbedded Mode will embed the devtools as a regular component in your application. You can style it however you'd like after that!\n\n```js\nimport { TanStackRouterDevtoolsPanel } from '@tanstack/react-router-devtools'\n\nfunction App() {\n return (\n <>\n <Router router={router} />\n <TanStackRouterDevtoolsPanel\n router={router}\n style={styles}\n className={className}\n />\n </>\n )\n}\n```\n\n### DevtoolsPanel Options\n\n- `router: Router`\n - The router instance to connect to.\n- `style: StyleObject`\n - The standard React style object used to style a component with inline styles.\n- `className: string`\n - The standard React className property used to style a component with classes.\n- `isOpen?: boolean`\n - A boolean variable indicating whether the panel is open or closed.\n- `setIsOpen?: (isOpen: boolean) => void`\n - A function that toggles the open and close state of the panel.\n- `handleDragStart?: (e: any) => void`\n - Handles the opening and closing the devtools panel.\n- `shadowDOMTarget?: ShadowRoot`\n - Specifies a Shadow DOM target for the devtools.\n - 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.\n\n# Frequently Asked Questions\n\nWelcome 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).\n\n## Why should you choose TanStack Router over another router?\n\nTo 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:\n\n- **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.\n- **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.\n\nThese 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.\n\n## Is TanStack Router a framework?\n\nTanStack 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.\nFor 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).\n\n## Should I commit my `routeTree.gen.ts` file into git?\n\nYes! Although the route tree file (i.e., `routeTree.gen.ts`) is generated by TanStack Router, it is essentially part of your application\u2019s runtime, not a build artifact. The route tree file is a critical part of your application\u2019s source code, and it is used by TanStack Router to build your application\u2019s routes at runtime.\n\nYou should commit this file into git so that other developers can use it to build your application.\n\n## Can I conditionally render the Root Route component?\n\nNo, the root route is always rendered as it is the entry point of your application.\n\nIf you need to conditionally render a route's component, this usually means that the page content needs to be different based on some condition (e.g. user authentication). For this use case, you should use a [Layout Route](../routing/routing-concepts.md#layout-routes) or a [Pathless Layout Route](../routing/routing-concepts.md#pathless-layout-routes) to conditionally render the content.\n\nYou can restrict access to these routes using a conditional check in the `beforeLoad` function of the route.\n\n<details>\n<summary>What does this look like?</summary>\n\n```tsx\n// src/routes/_pathless-layout.tsx\nimport { createFileRoute, Outlet } from '@tanstack/react-router'\nimport { isAuthenticated } from '../utils/auth'\n\nexport const Route = createFileRoute('/_pathless-layout', {\n beforeLoad: async () => {\n // Check if the user is authenticated\n const authed = await isAuthenticated()\n if (!authed) {\n // Redirect the user to the login page\n return '/login'\n }\n },\n component: PathlessLayoutRouteComponent,\n // ...\n})\n\nfunction PathlessLayoutRouteComponent() {\n return (\n <div>\n <h1>You are authed</h1>\n <Outlet />\n </div>\n )\n}\n```\n\n</details>\n\n";
1
+ declare const _default: "# Overview\n\n**TanStack Router is a router for building React and Solid applications**. Some of its features include:\n\n- 100% inferred TypeScript support\n- Typesafe navigation\n- Nested Routing and layout routes (with pathless layouts)\n- Built-in Route Loaders w/ SWR Caching\n- Designed for client-side data caches (TanStack Query, SWR, etc.)\n- Automatic route prefetching\n- Asynchronous route elements and error boundaries\n- File-based Route Generation\n- Typesafe JSON-first Search Params state management APIs\n- Path and Search Parameter Schema Validation\n- Search Param Navigation APIs\n- Custom Search Param parser/serializer support\n- Search param middleware\n- Route matching/loading middleware\n\nTo get started quickly, head to the next page. For a more lengthy explanation, buckle up while I bring you up to speed!\n\n## \"A Fork in the Route\"\n\nUsing a router to build applications is widely regarded as a must-have and is usually one of the first choices you\u2019ll make in your tech stack.\n\n## Why TanStack Router?\n\nTanStack Router delivers on the same fundamental expectations as other routers that you\u2019ve come to expect:\n\n- Nested routes, layout routes, grouped routes\n- File-based Routing\n- Parallel data loading\n- Prefetching\n- URL Path Params\n- Error Boundaries and Handling\n- SSR\n- Route Masking\n\nAnd it also delivers some new features that raise the bar:\n\n- 100% inferred TypeScript support\n- Typesafe navigation\n- Built-in SWR Caching for loaders\n- Designed for client-side data caches (TanStack Query, SWR, etc.)\n- Typesafe JSON-first Search Params state management APIs\n- Path and Search Parameter Schema Validation\n- Search Parameter Navigation APIs\n- Custom Search Param parser/serializer support\n- Search param middleware\n- Inherited Route Context\n- Mixed file-based and code-based routing\n\nLet\u2019s dive into some of the more important ones in more detail!\n\n## 100% Inferred TypeScript Support\n\nEverything these days is written \u201Cin Typescript\u201D or at the very least offers type definitions that are veneered over runtime functionality, but too few packages in the ecosystem actually design their APIs with TypeScript in mind. So while I\u2019m pleased that your router is auto-completing your option fields and catching a few property/method typos here and there, there is much more to be had.\n\n- TanStack Router is fully aware of all of your routes and their configuration at any given point in your code. This includes the path, path params, search params, context, and any other configuration you\u2019ve provided. Ultimately this means that you can navigate to any route in your app with 100% type safety and confidence that your link or navigate call will succeed.\n- TanStack Router provides lossless type-inference. It uses countless generic type parameters to enforce and propagate any type information you give it throughout the rest of its API and ultimately your app. No other router offers this level of type safety and developer confidence.\n\nWhat does all of that mean for you?\n\n- Faster feature development with auto-completion and type hints\n- Safer and faster refactors\n- Confidence that your code will work as expected\n\n## 1st Class Search Parameters\n\nSearch parameters are often an afterthought, treated like a black box of strings (or string) that you can parse and update, but not much else. Existing solutions are **not** type-safe either, adding to the caution that is required to deal with them. Even the most \"modern\" frameworks and routers leave it up to you to figure out how to manage this state. Sometimes they'll parse the search string into an object for you, or sometimes you're left to do it yourself with `URLSearchParams`.\n\nLet's step back and remember that **search params are the most powerful state manager in your entire application.** They are global, serializable, bookmarkable, and shareable making them the perfect place to store any kind of state that needs to survive a page refresh or a social share.\n\nTo live up to that responsibility, search parameters are a first-class citizen in TanStack Router. While still based on standard URLSearchParams, TanStack Router uses a powerful parser/serializer to manage deeper and more complex data structures in your search params, all while keeping them type-safe and easy to work with.\n\n**It's like having `useState` right in the URL!**\n\nSearch parameters are:\n\n- Automatically parsed and serialized as JSON\n- Validated and typed\n- Inherited from parent routes\n- Accessible in loaders, components, and hooks\n- Easily modified with the useSearch hook, Link, navigate, and router.navigate APIs\n- Customizable with a custom search filters and middleware\n- Subscribed via fine-grained search param selectors for efficient re-renders\n\nOnce you start using TanStack Router's search parameters, you'll wonder how you ever lived without them.\n\n## Built-In Caching and Friendly Data Loading\n\nData loading is a critical part of any application and while most existing routers offer some form of critical data loading APIs, they often fall short when it comes to caching and data lifecycle management. Existing solutions suffer from a few common problems:\n\n- No caching at all. Data is always fresh, but your users are left waiting for frequently accessed data to load over and over again.\n- Overly-aggressive caching. Data is cached for too long, leading to stale data and a poor user experience.\n- Blunt invalidation strategies and APIs. Data may be invalidated too often, leading to unnecessary network requests and wasted resources, or you may not have any fine-grained control over when data is invalidated at all.\n\nTanStack Router solves these problems with a two-prong approach to caching and data loading:\n\n### Built-in Cache\n\nTanStack Router provides a light-weight built-in caching layer that works seamlessly with the Router. This caching layer is loosely based on TanStack Query, but with fewer features and a much smaller API surface area. Like TanStack Query, sane but powerful defaults guarantee that your data is cached for reuse, invalidated when necessary, and garbage collected when not in use. It also provides a simple API for invalidating the cache manually when needed.\n\n### Flexible & Powerful Data Lifecycle APIs\n\nTanStack Router is designed with a flexible and powerful data loading API that more easily integrates with existing data fetching libraries like TanStack Query, SWR, Apollo, Relay, or even your own custom data fetching solution. Configurable APIs like `context`, `beforeLoad`, `loaderDeps` and `loader` work in unison to make it easy to define declarative data dependencies, prefetch data, and manage the lifecycle of an external data source with ease.\n\n## Inherited Route Context\n\nTanStack Router's router and route context is a powerful feature that allows you to define context that is specific to a route which is then inherited by all child routes. Even the router and root routes themselves can provide context. Context can be built up both synchronously and asynchronously, and can be used to share data, configuration, or even functions between routes and route configurations. This is especially useful for scenarios like:\n\n- Authentication and Authorization\n- Hybrid SSR/CSR data fetching and preloading\n- Theming\n- Singletons and global utilities\n- Curried or partial application across preloading, loading, and rendering stages\n\nAlso, what would route context be if it weren't type-safe? TanStack Router's route context is fully type-safe and inferred at zero cost to you.\n\n## File-based and/or Code-Based Routing\n\nTanStack Router supports both file-based and code-based routing at the same time. This flexibility allows you to choose the approach that best fits your project's needs.\n\nTanStack Router's file-based routing approach is uniquely user-facing. Route configuration is generated for you either by the Vite plugin or TanStack Router CLI, leaving the usage of said generated code up to you! This means that you're always in total control of your routes and router, even if you use file-based routing.\n\n## Acknowledgements\n\nTanStack Router builds on concepts and patterns popularized by many other OSS projects, including:\n\n- [TRPC](https://trpc.io/)\n- [Remix](https://remix.run)\n- [Chicane](https://swan-io.github.io/chicane/)\n- [Next.js](https://nextjs.org)\n\nWe acknowledge the investment, risk and research that went into their development, but are excited to push the bar they have set even higher.\n\n## Let's go!\n\nEnough overview, there's so much more to do with TanStack Router. Hit that next button and let's get started!\n\n# Quick Start\n\nTanStack Router can be quickly added to any existing React project or used to scaffold a new one.\n\n## TanStack Router Installation\n\n### Requirements\n\nBefore installing TanStack router, please ensure your project meets the following requirements:\n\n[//]: # 'Requirements'\n\n- `react` v18 or later with `createRoot` support.\n- `react-dom` v18 or later.\n\n[//]: # 'Requirements'\n\n> [!NOTE]\n> 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.\n\nTanStack 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).\n\n### Download and Install\n\nTo install TanStack Router in your project, run the following command using your preferred package manager:\n\n[//]: # 'installCommand'\n\n```sh\nnpm install @tanstack/react-router\n# or\npnpm add @tanstack/react-router\n#or\nyarn add @tanstack/react-router\n# or\nbun add @tanstack/react-router\n# or\ndeno add npm:@tanstack/react-router\n```\n\n[//]: # 'installCommand'\n\nOnce installed, you can verify the installation by checking your `package.json` file for the dependency.\n\n[//]: # 'packageJson'\n\n```json\n{\n \"dependencies\": {\n \"@tanstack/react-router\": \"^x.x.x\"\n }\n}\n```\n\n[//]: # 'packageJson'\n\n## New Project Setup\n\nTo 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.\n\n> [!TIP]\n> 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).\n\nTo create a new project, run the following command in your terminal:\n\n[//]: # 'createAppCommand'\n\n```sh\nnpx create-tsrouter-app@latest\n```\n\n[//]: # 'createAppCommand'\n\nThe CLI will guide you through a short series of prompts to customize your setup, including options for:\n\n[//]: # 'CLIPrompts'\n\n- File-based or code-based route configuration\n- TypeScript support\n- Tailwind CSS integration\n- Toolchain setup\n- Git initialization\n\n[//]: # 'CLIPrompts'\n\nOnce 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:\n\n```sh\ncd your-project-name\nnpm run dev\n```\n\n### Routing Options\n\nTanStack Router supports both file-based and code-based route configurations, allowing you to choose the approach that best fits your workflow.\n\n#### File-Based Route Generation\n\nThe 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.\n\nTo create a new project using file-based route generation, run the following command:\n\n[//]: # 'createAppCommandFileBased'\n\n```sh\nnpx create-tsrouter-app@latest my-app --template file-router\n```\n\n[//]: # 'createAppCommandFileBased'\n\nThis 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:\n\n```sh\ncd my-app\nnpm run dev\n```\n\n#### Code-Based Route Configuration\n\nIf 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.\n\n[//]: # 'createAppCommandCodeBased'\n\n```sh\nnpx create-tsrouter-app@latest my-app\n```\n\n[//]: # 'createAppCommandCodeBased'\n\nSimilar 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:\n\n```sh\ncd my-app\nnpm run dev\n```\n\nWith either approach, you can now start building your React application with TanStack Router!\n\n# Decisions on Developer Experience\n\nWhen people first start using TanStack Router, they often have a lot of questions that revolve around the following themes:\n\n> Why do I have to do things this way?\n\n> Why is it done this way? and not that way?\n\n> I'm used to doing it this way, why should I change?\n\nAnd 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.\n\nBut 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.\n\n## TanStack Router's origin story\n\nIt'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.\n\nAnd 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.\n\n## How does TanStack Router achieve this?\n\n> TypeScript! TypeScript! TypeScript!\n\nEvery 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.\n\nBut to achieve this, we had to make some decisions that deviate from the norms in the routing world.\n\n1. [**Route configuration boilerplate?**](#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.\n2. [**TypeScript module declaration for the router?**](#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.\n3. [**Why push for file-based routing over code-based?**](#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.\n\n> 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.\n\n## Why is the Router's configuration done this way?\n\nWhen 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.\n\nThis 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.\n\n> Can I use JSX to define my routes?\n\nUsing 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.\n\n```tsx\n// \u26D4\uFE0F This is not possible\nfunction App() {\n return (\n <Router>\n <Route path=\"/posts\" component={PostsPage} />\n <Route path=\"/posts/$postId\" component={PostIdPage} />\n {/* ... */}\n </Router>\n // ^? TypeScript cannot infer the routes in this configuration\n )\n}\n```\n\nAnd 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.\n\n> Maybe I could define my routes as a tree of nested objects?\n\n```tsx\n// \u26D4\uFE0F This file will just keep growing and growing...\nconst router = createRouter({\n routes: {\n posts: {\n component: PostsPage, // /posts\n children: {\n $postId: {\n component: PostIdPage, // /posts/$postId\n },\n },\n },\n // ...\n },\n})\n```\n\nAt 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:\n\n- **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.\n- **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.\n\nThis only gets worse as you begin to use more features of the router, such as nested context, loaders, search param validation, etc.\n\n> So, what's the best way to define my routes?\n\nWhat 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.\n\nYou can read more about [code-based routing](../routing/code-based-routing.md) to see how to define your routes in this way.\n\n> [!TIP]\n> Finding Code-based routing to be a bit too cumbersome? See why [file-based routing](#why-is-file-based-routing-the-preferred-way-to-define-routes) is the preferred way to define your routes.\n\n## Declaring the Router instance for type inference\n\n> Why do I have to declare the `Router`?\n\n> This declaration stuff is way too complicated for me...\n\nOnce 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.\n\nThere were two approaches we considered for this:\n\n1. **Imports**: You could import the `Router` instance from the file where you created it and use it directly in your components.\n\n```tsx\nimport { router } from '@/src/app'\nexport const PostsIdLink = () => {\n return (\n <Link<typeof router> to=\"/posts/$postId\" params={{ postId: '123' }}>\n Go to post 123\n </Link>\n )\n}\n```\n\nA 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.\n\n2. **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.\n\nYou'll do this once in your application.\n\n```tsx\n// src/app.tsx\ndeclare module '@tanstack/react-router' {\n interface Register {\n router: typeof router\n }\n}\n```\n\nAnd then you can benefit from its auto-complete anywhere in your app without having to import it.\n\n```tsx\nexport const PostsIdLink = () => {\n return (\n <Link\n to=\"/posts/$postId\"\n // ^? TypeScript will auto-complete this for you\n params={{ postId: '123' }} // and this too!\n >\n Go to post 123\n </Link>\n )\n}\n```\n\nWe 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.\n\n## Why is file-based routing the preferred way to define routes?\n\n> Why are the docs pushing for file-based routing?\n\n> I'm used to defining my routes in a single file, why should I change?\n\nSomething 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.\n\n> [!TIP]\n> 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).\n\nAs 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.\n\nA 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.\n\n```tsx\nimport { createRoute } from '@tanstack/react-router'\nimport { postsRoute } from './postsRoute'\n\nexport const postsIndexRoute = createRoute({\n getParentRoute: () => postsRoute,\n path: '/',\n})\n```\n\nAt 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.\n\nAs such, this is a critical part of the route configuration and a point of failure if not done correctly.\n\nBut 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.\n\n> \uD83E\uDD2F If this route-tree were in its own file for an application with ~40-50 routes, it can easily grow up to 700+ lines.\n\n```tsx\nconst routeTree = rootRoute.addChildren([\n postsRoute.addChildren([postsIndexRoute, postsIdRoute]),\n])\n```\n\nThis 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.\n\nFinally, 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.\n\n```tsx\nimport { createRoute, lazyRouteComponent } from '@tanstack/react-router'\nimport { postsRoute } from './postsRoute'\n\nexport const postsIndexRoute = createRoute({\n getParentRoute: () => postsRoute,\n path: '/',\n component: lazyRouteComponent(() => import('../page-components/posts/index')),\n})\n```\n\nAll 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.\n\n... 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 \uD83E\uDD15.\n\n> So, why's file-based routing the preferred way?\n\nTanStack 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.\n\nThe 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:\n\n1. **Route configuration boilerplate**: It generates the boilerplate for your route configurations.\n2. **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.\n3. **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.\n\nLet's take a look at how the route configuration for the previous example would look like with file-based routing.\n\n```tsx\n// src/routes/posts/index.ts\nimport { createFileRoute } from '@tanstack/react-router'\n\nexport const Route = createFileRoute('/posts/')({\n component: () => 'Posts index component goes here!!!',\n})\n```\n\nThat'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.\n\nAt 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.\n\nCheck 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.\n\n# Devtools\n\n> Link, take this sword... I mean Devtools!... to help you on your way!\n\nWave your hands in the air and shout hooray because TanStack Router comes with dedicated devtools! \uD83E\uDD73\n\nWhen you begin your TanStack Router journey, you'll want these devtools by your side. They help visualize all of the inner workings of TanStack Router and will likely save you hours of debugging if you find yourself in a pinch!\n\n## Installation\n\nThe devtools are a separate package that you need to install:\n\n```sh\nnpm install @tanstack/react-router-devtools\n```\n\nor\n\n```sh\npnpm add @tanstack/react-router-devtools\n```\n\nor\n\n```sh\nyarn add @tanstack/react-router-devtools\n```\n\nor\n\n```sh\nbun add @tanstack/react-router-devtools\n```\n\n## Import the Devtools\n\n```js\nimport { TanStackRouterDevtools } from '@tanstack/react-router-devtools'\n```\n\n## Using Devtools in production\n\nThe Devtools, if imported as `TanStackRouterDevtools` will not be shown in production. If you want to have devtools in an environment with `process.env.NODE_ENV === 'production'`, use instead `TanStackRouterDevtoolsInProd`, which has all the same options:\n\n```tsx\nimport { TanStackRouterDevtoolsInProd } from '@tanstack/react-router-devtools'\n```\n\n## Using inside of the `RouterProvider`\n\nThe easiest way for the devtools to work is to render them inside of your root route (or any other route). This will automatically connect the devtools to the router instance.\n\n```tsx\nconst rootRoute = createRootRoute({\n component: () => (\n <>\n <Outlet />\n <TanStackRouterDevtools />\n </>\n ),\n})\n\nconst routeTree = rootRoute.addChildren([\n // ... other routes\n])\n\nconst router = createRouter({\n routeTree,\n})\n\nfunction App() {\n return <RouterProvider router={router} />\n}\n```\n\n## Manually passing the Router Instance\n\nIf rendering the devtools inside of the `RouterProvider` isn't your cup of tea, a `router` prop for the devtools accepts the same `router` instance you pass to the `Router` component. This makes it possible to place the devtools anywhere on the page, not just inside the provider:\n\n```tsx\nfunction App() {\n return (\n <>\n <RouterProvider router={router} />\n <TanStackRouterDevtools router={router} />\n </>\n )\n}\n```\n\n## Floating Mode\n\nFloating Mode will mount the devtools as a fixed, floating element in your app and provide a toggle in the corner of the screen to show and hide the devtools. This toggle state will be stored and remembered in localStorage across reloads.\n\nPlace the following code as high in your React app as you can. The closer it is to the root of the page, the better it will work!\n\n```js\nimport { TanStackRouterDevtools } from '@tanstack/react-router-devtools'\n\nfunction App() {\n return (\n <>\n <Router />\n <TanStackRouterDevtools initialIsOpen={false} />\n </>\n )\n}\n```\n\n### Devtools Options\n\n- `router: Router`\n - The router instance to connect to.\n- `initialIsOpen: Boolean`\n - Set this `true` if you want the devtools to default to being open.\n- `panelProps: PropsObject`\n - Use this to add props to the panel. For example, you can add `className`, `style` (merge and override default style), etc.\n- `closeButtonProps: PropsObject`\n - Use this to add props to the close button. For example, you can add `className`, `style` (merge and override default style), `onClick` (extend default handler), etc.\n- `toggleButtonProps: PropsObject`\n - Use this to add props to the toggle button. For example, you can add `className`, `style` (merge and override default style), `onClick` (extend default handler), etc.\n- `position?: \"top-left\" | \"top-right\" | \"bottom-left\" | \"bottom-right\"`\n - Defaults to `bottom-left`.\n - The position of the TanStack Router logo to open and close the devtools panel.\n- `shadowDOMTarget?: ShadowRoot`\n - Specifies a Shadow DOM target for the devtools.\n - 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.\n- `containerElement?: string | any`\n - Use this to render the devtools inside a different type of container element for ally purposes.\n - Any string which corresponds to a valid intrinsic JSX element is allowed.\n - Defaults to 'footer'.\n\n## Fixed Mode\n\nTo control the position of the devtools, import the `TanStackRouterDevtoolsPanel`:\n\n```js\nimport { TanStackRouterDevtoolsPanel } from '@tanstack/react-router-devtools'\n```\n\nIt can then be attached to provided shadow DOM target:\n\n```js\n<TanStackRouterDevtoolsPanel\n shadowDOMTarget={shadowContainer}\n router={router}\n/>\n```\n\nClick [here](https://tanstack.com/router/latest/docs/framework/react/examples/basic-devtools-panel) to see a live example of this in StackBlitz.\n\n## Embedded Mode\n\nEmbedded Mode will embed the devtools as a regular component in your application. You can style it however you'd like after that!\n\n```js\nimport { TanStackRouterDevtoolsPanel } from '@tanstack/react-router-devtools'\n\nfunction App() {\n return (\n <>\n <Router router={router} />\n <TanStackRouterDevtoolsPanel\n router={router}\n style={styles}\n className={className}\n />\n </>\n )\n}\n```\n\n### DevtoolsPanel Options\n\n- `router: Router`\n - The router instance to connect to.\n- `style: StyleObject`\n - The standard React style object used to style a component with inline styles.\n- `className: string`\n - The standard React className property used to style a component with classes.\n- `isOpen?: boolean`\n - A boolean variable indicating whether the panel is open or closed.\n- `setIsOpen?: (isOpen: boolean) => void`\n - A function that toggles the open and close state of the panel.\n- `handleDragStart?: (e: any) => void`\n - Handles the opening and closing the devtools panel.\n- `shadowDOMTarget?: ShadowRoot`\n - Specifies a Shadow DOM target for the devtools.\n - 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.\n\n# Frequently Asked Questions\n\nWelcome 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).\n\n## Why should you choose TanStack Router over another router?\n\nTo 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:\n\n- **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.\n- **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.\n\nThese 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.\n\n## Is TanStack Router a framework?\n\nTanStack 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.\nFor 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).\n\n## Should I commit my `routeTree.gen.ts` file into git?\n\nYes! Although the route tree file (i.e., `routeTree.gen.ts`) is generated by TanStack Router, it is essentially part of your application\u2019s runtime, not a build artifact. The route tree file is a critical part of your application\u2019s source code, and it is used by TanStack Router to build your application\u2019s routes at runtime.\n\nYou should commit this file into git so that other developers can use it to build your application.\n\n## Can I conditionally render the Root Route component?\n\nNo, the root route is always rendered as it is the entry point of your application.\n\nIf you need to conditionally render a route's component, this usually means that the page content needs to be different based on some condition (e.g. user authentication). For this use case, you should use a [Layout Route](../routing/routing-concepts.md#layout-routes) or a [Pathless Layout Route](../routing/routing-concepts.md#pathless-layout-routes) to conditionally render the content.\n\nYou can restrict access to these routes using a conditional check in the `beforeLoad` function of the route.\n\n<details>\n<summary>What does this look like?</summary>\n\n```tsx\n// src/routes/_pathless-layout.tsx\nimport { createFileRoute, Outlet } from '@tanstack/react-router'\nimport { isAuthenticated } from '../utils/auth'\n\nexport const Route = createFileRoute('/_pathless-layout', {\n beforeLoad: async () => {\n // Check if the user is authenticated\n const authed = await isAuthenticated()\n if (!authed) {\n // Redirect the user to the login page\n return '/login'\n }\n },\n component: PathlessLayoutRouteComponent,\n // ...\n})\n\nfunction PathlessLayoutRouteComponent() {\n return (\n <div>\n <h1>You are authed</h1>\n <Outlet />\n </div>\n )\n}\n```\n\n</details>\n\n";
2
2
  export default _default;
@@ -155,7 +155,8 @@ Before installing TanStack router, please ensure your project meets the followin
155
155
 
156
156
  [//]: # 'Requirements'
157
157
 
158
- > [!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.
158
+ > [!NOTE]
159
+ > 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.
159
160
 
160
161
  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).
161
162
 
@@ -197,7 +198,8 @@ Once installed, you can verify the installation by checking your \`package.json\
197
198
 
198
199
  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.
199
200
 
200
- > [!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).
201
+ > [!TIP]
202
+ > 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).
201
203
 
202
204
  To create a new project, run the following command in your terminal:
203
205
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tanstack/react-router",
3
- "version": "1.139.0",
3
+ "version": "1.139.3",
4
4
  "description": "Modern and scalable routing for React applications",
5
5
  "author": "Tanner Linsley",
6
6
  "license": "MIT",
@@ -80,7 +80,7 @@
80
80
  "tiny-invariant": "^1.3.3",
81
81
  "tiny-warning": "^1.0.3",
82
82
  "@tanstack/history": "1.139.0",
83
- "@tanstack/router-core": "1.139.0"
83
+ "@tanstack/router-core": "1.139.3"
84
84
  },
85
85
  "devDependencies": {
86
86
  "@testing-library/jest-dom": "^6.6.3",
@@ -108,20 +108,22 @@ export function Transitioner() {
108
108
  }, [isPagePending, previousIsPagePending, router])
109
109
 
110
110
  useLayoutEffect(() => {
111
- // The router was pending and now it's not
112
111
  if (previousIsAnyPending && !isAnyPending) {
112
+ const changeInfo = getLocationChangeInfo(router.state)
113
113
  router.emit({
114
114
  type: 'onResolved',
115
- ...getLocationChangeInfo(router.state),
115
+ ...changeInfo,
116
116
  })
117
117
 
118
- router.__store.setState((s) => ({
118
+ router.__store.setState((s: typeof router.state) => ({
119
119
  ...s,
120
120
  status: 'idle',
121
121
  resolvedLocation: s.location,
122
122
  }))
123
123
 
124
- handleHashScroll(router)
124
+ if (changeInfo.hrefChanged) {
125
+ handleHashScroll(router)
126
+ }
125
127
  }
126
128
  }, [isAnyPending, previousIsAnyPending, router])
127
129