Skip to main content
tanstack-router Provides TanStack Router patterns — file-based routes, typed params/search, layouts, loaders. Use when setting up routes, implementing navigation, or configuring route loaders.
Zur Installation springen Skills Marktplatz Entdecken und erkunden Sie KI-Skills, die von der Community erstellt wurden.
Mit Codex oder Claude installieren Kopieren Sie diesen Prompt, fügen Sie ihn in Codex, Claude oder einen anderen Assistant ein und lassen Sie die Skill-Seite prüfen und installieren.
Prompt kopierenPrompt-Details anzeigen Ein direkter Befehl überspringt den Prüf-Prompt. Prüfen Sie die Quelle, bevor Sie ihn ausführen.
npx skills add https://github.com/MadAppGang/magus --skill tanstack-routerDer Befehl bleibt in einer Zeile. Scrollen Sie horizontal, um ihn vor dem Kopieren vollständig zu prüfen.
Sie bevorzugen eine lokale Kopie? Laden Sie die Dateien herunter, die SkillsMP derzeit vorliegen.
ZIP herunterladen Herunterladen... Mehr aus diesem Repository Picks the browser-use agent brain LLM per task. Use when choosing a model for retry_with_browser_use_agent or a cloud session, or the user mentions a cheap, slow, or smart model.
Reference for the Browser Use MCP tools — parameters, returns, session lifecycle. Use when navigating, clicking, typing, evaluating JS, or extracting page content.
Visual UI debugging — screenshot capture and analysis, responsive layout checking at multiple viewport sizes, CSS validation via DOM state, visual regression detection, before/after state comparison.
SOC
Basierend auf der SOC-Berufsklassifikation
name tanstack-router description Provides TanStack Router patterns — file-based routes, typed params/search, layouts, loaders. Use when setting up routes, implementing navigation, or configuring route loaders. disable-model-invocation true
TanStack Router Patterns
Type-safe, file-based routing for React applications with TanStack Router.
Installation
pnpm add @tanstack/react-router
pnpm add -D @tanstack/router-plugin
import { TanStackRouterVite } from '@tanstack/router-plugin/vite'
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig ({
plugins : [
react (),
TanStackRouterVite (),
],
})
Automatic Code Splitting (Recommended)
TanStack Router v1.x+ (2025) introduces automatic code splitting that separates critical route configuration from non-critical components.
import { TanStackRouterVite } from '@tanstack/router-plugin/vite'
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'
export default defineConfig ({
plugins : [
react (),
TanStackRouterVite ({
autoCodeSplitting : true ,
}),
],
})
Critical (Always Loaded) Non-Critical (Lazy Loaded) Route configuration Component Loaders Error component Search params validation Pending component beforeLoad Not-found component
Smaller initial bundle (route config without components)
Automatic optimization (no manual .lazy.tsx files needed)
Better perceived performance (loaders start immediately)
Recommended for all new projects
Existing projects: Enable and test bundle sizes
Large apps benefit most (many routes)
Bootstrap
import { StrictMode } from 'react'
import ReactDOM from 'react-dom/client'
import { RouterProvider , createRouter } from '@tanstack/react-router'
import { routeTree } from './routeTree.gen'
const router = createRouter ({ routeTree })
declare module '@tanstack/react-router' {
interface Register {
router : typeof router
}
}
ReactDOM .createRoot (document .getElementById ('root' )!).render (
<StrictMode >
<RouterProvider router ={router} />
</StrictMode >
)
File-Based Routes src/routes/
├── __root.tsx # Root layout (Outlet, providers)
├── index.tsx # "/" route
├── about.tsx # "/about" route
├── users/
│ ├── index.tsx # "/users" route
│ └── $userId.tsx # "/users/:userId" route (dynamic)
└── posts/
├── $postId/
│ ├── index.tsx # "/posts/:postId" route
│ └── edit.tsx # "/posts/:postId/edit" route
└── index.tsx # "/posts" route
__root.tsx - Root layout (contains <Outlet />)
index.tsx - Index route for that path
$param.tsx - Dynamic parameter (e.g., $userId → :userId)
_layout.tsx - Layout route (no URL segment)
route.lazy.tsx - Lazy-loaded route
Virtual File Routes Virtual file routes allow the router to auto-generate route anchors without physical files:
src/routes/
├── __root.tsx # Root layout
├── index.tsx # "/" (physical file)
├── about.lazy.tsx # "/about" (virtual route, lazy only)
└── users/
├── index.tsx # "/users" (physical)
└── $userId.lazy.tsx # "/users/:userId" (virtual, lazy only)
Key Insight: If you only need a component (no loader, no search validation), you can delete the base route file. The router auto-generates a virtual anchor for .lazy.tsx files.
Example - Minimal About Page:
import { createLazyFileRoute } from '@tanstack/react-router'
export const Route = createLazyFileRoute ('/about' )({
component : () => <div > About Us</div > ,
})
When Virtual Routes Make Sense:
Static pages with no data fetching
Simple UI components
When you want maximum code splitting
Root Layout
import { createRootRoute, Outlet } from '@tanstack/react-router'
import { TanStackRouterDevtools } from '@tanstack/router-devtools'
export const Route = createRootRoute ({
component : () => (
<>
<nav >
<Link to ="/" > Home</Link >
<Link to ="/about" > About</Link >
<Link to ="/users" > Users</Link >
</nav >
<main >
<Outlet /> {/* Child routes render here */}
</main >
<TanStackRouterDevtools /> {/* Auto-hides in production */}
</>
),
})
Basic Route
import { createFileRoute } from '@tanstack/react-router'
export const Route = createFileRoute ('/about' )({
component : AboutComponent ,
})
function AboutComponent ( ) {
return <div > About Page</div >
}
Dynamic Routes with Params
import { createFileRoute } from '@tanstack/react-router'
export const Route = createFileRoute ('/users/$userId' )({
component : UserComponent ,
})
function UserComponent ( ) {
const { userId } = Route .useParams ()
return <div > User ID: {userId}</div >
}
Typed Search Params
import { createFileRoute } from '@tanstack/react-router'
import { z } from 'zod'
const userSearchSchema = z.object ({
page : z.number ().default (1 ),
filter : z.enum (['active' , 'inactive' , 'all' ]).default ('all' ),
search : z.string ().optional (),
})
export const Route = createFileRoute ('/users/' )({
validateSearch : userSearchSchema,
component : UsersComponent ,
})
function UsersComponent ( ) {
const { page, filter, search } = Route .useSearch ()
return (
<div >
<p > Page: {page}</p >
<p > Filter: {filter}</p >
{search && <p > Search: {search}</p > }
</div >
)
}
Navigation with Link import { Link } from '@tanstack/react-router'
<Link to="/about" >About </Link >
<Link to ="/users/$userId" params ={{ userId: '123 ' }}>
View User
</Link >
<Link
to ="/users"
search ={{ page: 2 , filter: 'active ' }}
>
Users Page 2
</Link >
<Link to ="/details" state ={{ from: 'home ' }}>
Details
</Link >
<Link
to ="/about"
activeProps ={{ className: 'text-blue-600 font-bold ' }}
inactiveProps ={{ className: 'text-gray-600 ' }}
>
About
</Link >
Programmatic Navigation import { useNavigate } from '@tanstack/react-router'
function MyComponent ( ) {
const navigate = useNavigate ()
const handleClick = ( ) => {
navigate ({ to : '/users' })
navigate ({ to : '/users/$userId' , params : { userId : '123' } })
navigate ({ to : '/users' , search : { page : 2 } })
navigate ({ to : '/login' , replace : true })
navigate ({ to : '..' })
}
return <button onClick ={handleClick} > Navigate</button >
}
Route Loaders (Data Fetching)
import { createFileRoute } from '@tanstack/react-router'
export const Route = createFileRoute ('/users/$userId' )({
loader : async ({ params }) => {
const user = await fetchUser (params.userId )
return { user }
},
component : UserComponent ,
})
function UserComponent ( ) {
const { user } = Route .useLoaderData ()
return <div > {user.name}</div >
}
With TanStack Query Integration (see tanstack-query skill for details):
import { queryClient } from '@/app/queryClient'
import { userQueryOptions } from '@/features/users/queries'
export const Route = createFileRoute ('/users/$userId' )({
loader : ({ params } ) =>
queryClient.ensureQueryData (userQueryOptions (params.userId )),
component : UserComponent ,
})
Manual Code Splitting (.lazy.tsx Pattern) For fine-grained control over code splitting, split routes into critical and lazy files:
Critical Route File (posts.tsx):
import { createFileRoute } from '@tanstack/react-router'
import { postsQueryOptions } from '@/features/posts/queries'
import { queryClient } from '@/app/queryClient'
export const Route = createFileRoute ('/posts' )({
loader : () => queryClient.ensureQueryData (postsQueryOptions ()),
validateSearch : (search ) => postsSearchSchema.parse (search),
})
Lazy Route File (posts.lazy.tsx):
import { createLazyFileRoute } from '@tanstack/react-router'
import { Posts } from '@/features/posts/components/Posts'
export const Route = createLazyFileRoute ('/posts' )({
component : Posts ,
pendingComponent : () => <PostsSkeleton /> ,
errorComponent : ({ error } ) => <PostsError error ={error} /> ,
})
component - The main route component
errorComponent - Error boundary UI
pendingComponent - Loading/suspense UI
notFoundComponent - 404 UI for this route
Critical-Only Properties (NOT in lazy):
loader / loaderDeps
beforeLoad
validateSearch
search (search middleware)
context
Best Practice: Use automatic code splitting (autoCodeSplitting: true) unless you need specific control over what goes in each file.
Type-Safe Route Data Access (getRouteApi) When building components outside the route file, use getRouteApi for type-safe access:
import { getRouteApi } from '@tanstack/react-router'
const routeApi = getRouteApi ('/posts/$postId' )
export function PostHeader ( ) {
const { postId } = routeApi.useParams ()
const { post } = routeApi.useLoaderData ()
const { view } = routeApi.useSearch ()
const context = routeApi.useRouteContext ()
return (
<header >
<h1 > {post.title}</h1 >
<span > Viewing: {view}</span >
</header >
)
}
useParams() - Route parameters
useSearch() - Search/query params
useLoaderData() - Data from loader
useRouteContext() - Route context
useMatch() - Full route match object
Components in separate files from route definition
Shared components used across routes
Avoiding circular imports
Cleaner separation of concerns
Important: The route path string must exactly match the route definition.
Layouts Layout Route (_layout.tsx - no URL segment):
import { createFileRoute, Outlet } from '@tanstack/react-router'
export const Route = createFileRoute ('/_layout' )({
component : LayoutComponent ,
})
function LayoutComponent ( ) {
return (
<div className ="dashboard-layout" >
<Sidebar />
<div className ="content" >
<Outlet /> {/* Child routes */}
</div >
</div >
)
}
Route Groups Route groups organize files without affecting URLs using parentheses:
src/routes/
├── (auth)/ # Group (not in URL)
│ ├── login.tsx # "/login"
│ ├── register.tsx # "/register"
│ └── forgot-password.tsx # "/forgot-password"
├── (dashboard)/ # Group (not in URL)
│ ├── _layout.tsx # Shared dashboard layout
│ ├── index.tsx # "/" (or "/dashboard")
│ ├── analytics.tsx # "/analytics"
│ └── settings.tsx # "/settings"
└── __root.tsx
Organize related routes without nesting URLs
Apply shared layouts to grouped routes
Better file organization in large apps
No URL pollution
Example - Auth Group Layout:
export const Route = createFileRoute ('/(auth)/_layout' )({
component : () => (
<div className ="auth-layout" >
<Logo />
<Outlet />
</div >
),
})
Loading States export const Route = createFileRoute ('/users' )({
loader : async () => {
const users = await fetchUsers ()
return { users }
},
pendingComponent : () => <Spinner /> ,
errorComponent : ({ error } ) => <ErrorMessage > {error.message}</ErrorMessage > ,
component : UsersComponent ,
})
Error Handling import { ErrorComponent } from '@tanstack/react-router'
export const Route = createFileRoute ('/users' )({
loader : async () => {
const users = await fetchUsers ()
if (!users) throw new Error ('Failed to load users' )
return { users }
},
errorComponent : ({ error, reset } ) => (
<div >
<h1 > Error loading users</h1 >
<p > {error.message}</p >
<button onClick ={reset} > Try Again</button >
</div >
),
component : UsersComponent ,
})
Route Context
export const Route = createRootRoute ({
beforeLoad : () => ({
user : getCurrentUser (),
}),
component : RootComponent ,
})
export const Route = createFileRoute ('/dashboard' )({
component : function Dashboard ( ) {
const { user } = Route .useRouteContext ()
return <div > Welcome, {user.name}</div >
},
})
Route Guards / Auth
import { createFileRoute, redirect } from '@tanstack/react-router'
export const Route = createFileRoute ('/_authenticated' )({
beforeLoad : ({ context } ) => {
if (!context.user ) {
throw redirect ({ to : '/login' })
}
},
component : Outlet ,
})
Preloading <Link
to="/users/$userId"
params={{ userId : '123' }}
preload="intent"
>
View User
</Link >
preload="intent" - Preload on hover/focus
preload="render" - Preload when link renders
preload={false} - No preload (default)
DevTools import { TanStackRouterDevtools } from '@tanstack/router-devtools'
<TanStackRouterDevtools position="bottom-right" />
Auto-hides in production builds.
Best Practices
Use Type-Safe Navigation - Let TypeScript catch routing errors at compile time
Validate Search Params - Use Zod schemas for search params
Prefetch Data in Loaders - Integrate with TanStack Query for optimal data fetching
Use Layouts for Shared UI - Avoid duplicating layout code across routes
Lazy Load Routes - Use route.lazy.tsx for code splitting
Leverage Route Context - Share data down the route tree efficiently
Common Patterns Catch-All (Splat) Routes:
export const Route = createFileRoute ('/files/$' )({
component : FileViewer ,
})
function FileViewer ( ) {
const { _splat } = Route .useParams ()
return <div > File: {_splat}</div >
}
v2 Migration Note:
In TanStack Router v2 (upcoming), splat routes use _splat key consistently:
v1: params['*'] or params._splat (both work)
v2: Only params._splat (star deprecated)
const { _splat } = Route .useParams ()
const splat = Route .useParams ()['*' ]
export const Route = createFileRoute ('/$' )({
component : () => <div > 404 Not Found</div > ,
})
const searchSchema = z.object ({
optional : z.string ().optional (),
})
Multi-Level Dynamic Routes:
/posts/$postId/comments/$commentId
Production Best Practices (2026) Insights from large-scale TanStack Router deployments:
1. File Structure = URL Structure Colocate everything a page needs within its route folder:
src/routes/users/
├── $userId/
│ ├── index.tsx # Route definition
│ ├── index.lazy.tsx # Lazy component
│ ├── UserProfile.tsx # Page-specific component
│ └── useUserActions.ts # Page-specific hooks
└── index.tsx
Components/functions belong at the nearest shared ancestor in the hierarchy.
2. Let Router Handle Loading States
export const Route = createFileRoute ('/users/$userId' )({
loader : fetchUser,
pendingComponent : UserSkeleton ,
errorComponent : UserError ,
component : UserProfile ,
})
function UserProfile ( ) {
const { data, isLoading, error } = useUser ()
if (isLoading) return <Spinner />
if (error) return <Error />
return <div > {data.name}</div >
}
3. Preload Strategy
<Link
to="/users/$userId"
params={{ userId }}
preload="intent"
>
{user.name }
</Link >
<Link to ="/dashboard" preload ="render" >
Dashboard
</Link >
4. Search Params for Everything Shareable If users should be able to share or bookmark a specific view, use search params:
const searchSchema = z.object ({
tab : z.enum (['overview' , 'activity' , 'settings' ]).default ('overview' ),
page : z.number ().default (1 ),
sort : z.enum (['name' , 'date' , 'score' ]).optional (),
})
TanStack Start (Full-Stack Framework) TanStack Start is the full-stack meta-framework built on TanStack Router:
TanStack Router (routing)
Vite (bundler)
Nitro (server)
Vinxi (dev server)
New full-stack projects
Need SSR/SSG out of the box
Want alternatives to Next.js/Remix
Prefer TanStack's type-safety approach
When to Stick with Router + Vite:
SPAs without server requirements
Existing Vite projects
When you need maximum control
Note: Start is still maturing. For production SPAs in 2026, TanStack Router + Query + Vite remains the recommended stack.
Related Skills
tanstack-query - Server state management, caching, and route loader integration
react-typescript - React 19 patterns, component composition, and Actions
shadcn-ui - UI components with proper route integration
browser-debugging - DevTools and debugging TanStack Router
testing-frontend - Testing routes and navigation