tanstack-router

v2026.09.24

TanStack Router for React with file-based routing. Covers route definitions, layouts, authentication guards, loaders, and type-safe navigation. USE WHEN: user mentions "TanStack Router", "file-based routing", "type-safe routing", "route loaders", "beforeLoad", asks about "TanStack Router patterns", "typed navigation" DO NOT USE FOR: React Router v6 - use React Router docs, Next.js App Router - use `react-server-components`, Vue Router, Angular Router

GitHub
Install command
npx skhub add claude-dev-suite/tanstack-router
Markdown
SKILL.md

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

ConceptDescription
__root.tsxGlobal layout, providers
_layout.tsxRoute group layout
$param.tsxDynamic route segment
index.tsxIndex route
beforeLoadPre-navigation guard
loaderData fetching
notFound404 handling

Anti-Patterns

Anti-PatternWhy It's BadCorrect Approach
Fetching in componentsNot type-safe, duplicate requestsUse route loaders
Not using search param validationRuntime errorsUse Zod schema validation
Hardcoded navigation pathsType-unsafe, breaks on refactorUse typed Link and navigate
Mixing React Router patternsDifferent APIUse TanStack Router idioms
Not using beforeLoad for authAuth check in componentUse beforeLoad hook
Large route filesHard to maintainSplit into feature modules

Quick Troubleshooting

IssueLikely CauseSolution
Type error on navigationWrong route pathUse autocomplete from to prop
Loader not runningMissing loader in routeAdd loader to route definition
Redirect not workingWrong redirect syntaxUse throw redirect({ to: '...' })
Search params not updatingNot using useSearchUse Route.useSearch()
Route not foundFile naming wrongCheck file-based routing convention
Auth guard not firingNot in beforeLoadMove auth check to beforeLoad

Reference Documentation

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

Discovery
Tags

No tags published for this skill.

Version
Latest version metadata

Version

v2026.09.24

Published

Sep 24, 2026

Category

Uncategorized

License

MIT

Source path

skills/frontend-frameworks/tanstack-router

Default branch

main

Latest commit

9496306

Tree SHA

fe4e2f1