tanstack-router

TanStack Router Patterns

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "tanstack-router" with this command: npx skills add claude-dev-suite/claude-dev-suite/claude-dev-suite-claude-dev-suite-tanstack-router

TanStack Router Patterns

Deep Knowledge: Use mcp__documentation__fetch_docs with technology: tanstack-router for comprehensive documentation.

When NOT to Use This Skill

Skip this skill when:

  • Using React Router v6 (different API)

  • Building Next.js apps with App Router (use RSC patterns)

  • Working with Vue Router (use Vue-specific routing)

  • Using Angular Router (use Angular routing)

  • Client-side routing not needed (static sites)

File-Based Route Structure

src/routes/ ├── __root.tsx # Root layout ├── _authenticated.tsx # Auth guard layout ├── _authenticated/ │ ├── dashboard.tsx # /dashboard │ └── users/ │ ├── index.tsx # /users │ └── $userId.tsx # /users/:userId ├── login.tsx # /login └── register.tsx # /register

Root Route

// routes/__root.tsx import { createRootRoute, Outlet } from '@tanstack/react-router'; import { QueryClientProvider } from '@tanstack/react-query'; import { Toaster } from 'sonner'; import { queryClient } from '@/lib/query-client';

export const Route = createRootRoute({ component: RootComponent, });

function RootComponent() { return ( <QueryClientProvider client={queryClient}> <Outlet /> <Toaster richColors position="top-right" /> </QueryClientProvider> ); }

Auth Guard Layout

// routes/_authenticated.tsx import { createFileRoute, Outlet, redirect } from '@tanstack/react-router'; import { useAuthStore } from '@/stores/authStore'; import { MainLayout } from '@/layouts/MainLayout';

export const Route = createFileRoute('/_authenticated')({ beforeLoad: ({ location }) => { const isAuthenticated = useAuthStore.getState().isAuthenticated; if (!isAuthenticated) { throw redirect({ to: '/login', search: { redirect: location.href }, }); } }, component: AuthenticatedLayout, });

function AuthenticatedLayout() { return ( <MainLayout> <Outlet /> </MainLayout> ); }

Protected Route with Loader

// routes/_authenticated/users/index.tsx import { createFileRoute } from '@tanstack/react-router'; import { usersApi } from '@/api/users.api'; import { UserList } from '@/features/users/components/UserList';

export const Route = createFileRoute('/_authenticated/users/')({ loader: async () => { return usersApi.getAll(); }, component: UsersPage, });

function UsersPage() { const users = Route.useLoaderData(); return <UserList users={users} />; }

Dynamic Route with Params

// routes/_authenticated/users/$userId.tsx import { createFileRoute, notFound } from '@tanstack/react-router'; import { usersApi } from '@/api/users.api'; import { UserDetail } from '@/features/users/components/UserDetail';

export const Route = createFileRoute('/_authenticated/users/$userId')({ loader: async ({ params }) => { const user = await usersApi.getById(params.userId); if (!user) throw notFound(); return user; }, component: UserDetailPage, notFoundComponent: () => <div>User not found</div>, });

function UserDetailPage() { const user = Route.useLoaderData(); return <UserDetail user={user} />; }

Navigation

import { Link, useNavigate, useRouter } from '@tanstack/react-router';

// Declarative navigation <Link to="/users/$userId" params={{ userId: '123' }}> View User </Link>

// Programmatic navigation const navigate = useNavigate(); navigate({ to: '/dashboard' }); navigate({ to: '/users/$userId', params: { userId: '123' } });

// With search params navigate({ to: '/users', search: { page: 1, sort: 'name' }, });

// Go back const router = useRouter(); router.history.back();

Search Params with Validation

import { createFileRoute } from '@tanstack/react-router'; import { z } from 'zod';

const searchSchema = z.object({ page: z.number().default(1), search: z.string().optional(), sort: z.enum(['name', 'email', 'createdAt']).default('createdAt'), });

export const Route = createFileRoute('/_authenticated/users/')({ validateSearch: searchSchema, component: UsersPage, });

function UsersPage() { const { page, search, sort } = Route.useSearch(); // Type-safe search params }

Router Configuration

// router.ts import { createRouter } from '@tanstack/react-router'; import { routeTree } from './routeTree.gen';

export const router = createRouter({ routeTree, defaultPreload: 'intent', defaultPreloadStaleTime: 0, });

declare module '@tanstack/react-router' { interface Register { router: typeof router; } }

Key Concepts

Concept Description

__root.tsx

Global layout, providers

_layout.tsx

Route group layout

$param.tsx

Dynamic route segment

index.tsx

Index route

beforeLoad

Pre-navigation guard

loader

Data fetching

notFound

404 handling

Anti-Patterns

Anti-Pattern Why It's Bad Correct Approach

Fetching in components Not type-safe, duplicate requests Use route loaders

Not using search param validation Runtime errors Use Zod schema validation

Hardcoded navigation paths Type-unsafe, breaks on refactor Use typed Link and navigate

Mixing React Router patterns Different API Use TanStack Router idioms

Not using beforeLoad for auth Auth check in component Use beforeLoad hook

Large route files Hard to maintain Split into feature modules

Quick Troubleshooting

Issue Likely Cause Solution

Type error on navigation Wrong route path Use autocomplete from to prop

Loader not running Missing loader in route Add loader to route definition

Redirect not working Wrong redirect syntax Use throw redirect({ to: '...' })

Search params not updating Not using useSearch

Use Route.useSearch()

Route not found File naming wrong Check file-based routing convention

Auth guard not firing Not in beforeLoad

Move auth check to beforeLoad

Reference Documentation

Deep Knowledge: Use mcp__documentation__fetch_docs with technology: tanstack-router for comprehensive documentation.

  • File-based Routing

  • Auth Guards

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

Coding

token-optimization

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

tanstack-router

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

react-19

No summary provided by upstream source.

Repository SourceNeeds Review
Coding

webrtc

No summary provided by upstream source.

Repository SourceNeeds Review