TanStack Start is built on top of TanStack Router, so all of the features of TanStack Router are available to you.
Note
We highly recommend reading the TanStack Router documentation to learn more about the features and capabilities of TanStack Router. What you learn here is more of a high-level overview of TanStack Router and how it works in Start.
The router.tsx file is the file that will dictate the behavior of TanStack Router used within Start. It's located in the src directory of your project.
src/
├── router.tsx
src/
├── router.tsx
Here, you can configure everything from the default preloading functionality to caching staleness.
// src/router.tsx
import { createRouter } from '@tanstack/solid-router'
import { routeTree } from './routeTree.gen'
// You must export a getRouter function that
// returns a new router instance each time
export function getRouter() {
const router = createRouter({
routeTree,
scrollRestoration: true,
})
return router
}
// src/router.tsx
import { createRouter } from '@tanstack/solid-router'
import { routeTree } from './routeTree.gen'
// You must export a getRouter function that
// returns a new router instance each time
export function getRouter() {
const router = createRouter({
routeTree,
scrollRestoration: true,
})
return router
}
Start uses TanStack Router's file-based routing approach to ensure proper code-splitting and advanced type-safety.
You can find your routes in the src/routes directory.
src/
├── routes <-- This is where you put your routes
│ ├── __root.tsx
│ ├── index.tsx
│ ├── about.tsx
│ ├── posts.tsx
│ ├── posts/$postId.tsx
src/
├── routes <-- This is where you put your routes
│ ├── __root.tsx
│ ├── index.tsx
│ ├── about.tsx
│ ├── posts.tsx
│ ├── posts/$postId.tsx
The root route is the top-most route in the entire tree and encapsulates all other routes as children. It's found in the src/routes/__root.tsx file and must be named __root.tsx.
src/
├── routes
│ ├── __root.tsx <-- The root route
src/
├── routes
│ ├── __root.tsx <-- The root route
// src/routes/__root.tsx
import {
Outlet,
createRootRoute,
HeadContent,
Scripts,
} from '@tanstack/solid-router'
import type { SolidJSNode } from 'react'
export const Route = createRootRoute({
head: () => ({
meta: [
{
charSet: 'utf-8',
},
{
name: 'viewport',
content: 'width=device-width, initial-scale=1',
},
{
title: 'TanStack Start Starter',
},
],
}),
component: RootComponent,
})
function RootComponent() {
return (
<RootDocument>
<Outlet />
</RootDocument>
)
}
function RootDocument({ children }: Readonly<{ children: SolidJSNode }>) {
return (
<html>
<head>
<HeadContent />
</head>
<body>
{children}
<Scripts />
</body>
</html>
)
}
// src/routes/__root.tsx
import {
Outlet,
createRootRoute,
HeadContent,
Scripts,
} from '@tanstack/solid-router'
import type { SolidJSNode } from 'react'
export const Route = createRootRoute({
head: () => ({
meta: [
{
charSet: 'utf-8',
},
{
name: 'viewport',
content: 'width=device-width, initial-scale=1',
},
{
title: 'TanStack Start Starter',
},
],
}),
component: RootComponent,
})
function RootComponent() {
return (
<RootDocument>
<Outlet />
</RootDocument>
)
}
function RootDocument({ children }: Readonly<{ children: SolidJSNode }>) {
return (
<html>
<head>
<HeadContent />
</head>
<body>
{children}
<Scripts />
</body>
</html>
)
}
Notice the Scripts component at the bottom of the <body> tag. This is used to load all of the client-side JavaScript for the application and should always be included for proper functionality.
The HeadContent component is used to render the head, title, meta, link, and head-related script tags of the document.
It should be rendered in the <head> tag of your root route's layout.
The Outlet component is used to render the next potentially matching child route. <Outlet /> doesn't take any props and can be rendered anywhere within a route's component tree. If there is no matching child route, <Outlet /> will render null.
The Scripts component is used to render the body scripts of the document.
It should be rendered in the <body> tag of your root route's layout.
You may notice a routeTree.gen.ts file in your project.
src/
├── routeTree.gen.ts <-- The generated route tree file
src/
├── routeTree.gen.ts <-- The generated route tree file
This file is automatically generated when you run TanStack Start (via npm run dev or npm run start). This file contains the generated route tree and a handful of TS utilities that make TanStack Start's type-safety extremely fast and fully inferred.
You may gitignore this file, since it is a build artifact.
TanStack Router uses nested routing to match the URL with the correct component tree to render.
For example, given the following routes:
routes/
├── __root.tsx <-- Renders the <Root> component
├── posts.tsx <-- Renders the <Posts> component
├── posts.$postId.tsx <-- Renders the <Post> component
routes/
├── __root.tsx <-- Renders the <Root> component
├── posts.tsx <-- Renders the <Posts> component
├── posts.$postId.tsx <-- Renders the <Post> component
And the URL: /posts/123
The component tree would look like this:
<Root>
<Posts>
<Post />
</Posts>
</Root>
<Root>
<Posts>
<Post />
</Posts>
</Root>
There are a few different types of routes that you can create in your project.
There are also a few different utility route types that you can use to group and organize your routes
The route tree is configured in the src/routes directory.
To create a route, create a new file that corresponds to the path of the route you want to create. For example:
Path | Filename | Type |
---|---|---|
/ | index.tsx | Index Route |
/about | about.tsx | Static Route |
posts.tsx | "Layout" Route | |
/posts/ | posts/index.tsx | Index Route |
/posts/:postId | posts/$postId.tsx | Dynamic Route |
/rest/* | rest/$.tsx | Wildcard Route |
To define a route, use the createFileRoute function to export the route as the Route variable.
For example, to handle the /posts/:postId route, you would create a file named posts/$postId.tsx here:
src/
├── routes
│ ├── posts/$postId.tsx
src/
├── routes
│ ├── posts/$postId.tsx
Then, define the route like this:
// src/routes/posts/$postId.tsx
import { createFileRoute } from '@tanstack/solid-router'
export const Route = createFileRoute('/posts/$postId')({
component: PostComponent,
})
// src/routes/posts/$postId.tsx
import { createFileRoute } from '@tanstack/solid-router'
export const Route = createFileRoute('/posts/$postId')({
component: PostComponent,
})
Note
The path string passed to createFileRoute 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.
This has been just a high-level overview of how to configure routes using TanStack Router. For more detailed information, please refer to the TanStack Router documentation.
Your weekly dose of JavaScript news. Delivered every Monday to over 100,000 devs, for free.
Your weekly dose of JavaScript news. Delivered every Monday to over 100,000 devs, for free.