TanStack Router

Knowledge base from the official TanStack Router documentation (tanstack.com/router) — a fully type-safe router for React and Solid with first-class search-param state management, file-based and code-based routing, and built-in data loading. Use when building or debugging routing with createFileRoute/createRootRoute, wiring loaders/search-param validation, choosing file-based vs code-based routing, handling SSR/streaming, setting up route masking or navigation blocking, or integrating with TanStack Query.

57 capítulos

TanStack Router

Package: @tanstack/react-router (+ @tanstack/router-core, @tanstack/solid-router) | Chapters: 57 (14 Get Started + 41 Guides + 2 API) | Generated: 2026-08-25

How to Use This Skill

  • Without arguments - load Core Patterns below for the mental model shared across the whole router
  • With a concept name - ask about file-based routing, search params, loaders, SSR, route masking, etc.; I find and read the matching chapter
  • With a chapter - ask for ch010; I load that specific chapter
  • Browse - ask "what chapters do you have?" to see the full index

When you ask about a topic not covered in Core Patterns below, I will read the relevant chapter file before answering.


Core Patterns & Conventions

Routing style: Default to file-based routing (routes under src/routes/, generated via the tanstackRouter bundler plugin or tsr CLI into routeTree.gen.ts). Reach for code-based routing (createRoute + getParentRoute + addChildren) only when filesystem-based generation genuinely doesn't fit; the docs explicitly discourage it for most apps since it needs more boilerplate for equivalent results.

Route file naming tokens: $param (dynamic segment), $ alone (splat/catch-all), _prefix (pathless layout, wraps children with no URL segment), _suffix (non-nested, breaks out of parent's component tree), -prefix (excluded from routing entirely, for colocated non-route files), (group) (organizational folder, invisible in the URL), {-$param} (optional path parameter), [x] (escapes a literal routing-significant character). Route matching always sorts by specificity (index > static, most-specific-first > dynamic, longest-first > splat) regardless of declaration order.

Type safety foundation: Always register the router instance once via TypeScript declaration merging immediately after createRouter(): declare module '@tanstack/react-router' { interface Register { router: typeof router } }. This single step is what makes Link, useNavigate, useParams, etc. type-safe project-wide without importing the router instance everywhere. Router-wide hooks used inside a specific route need a from hint (route ID/path, or Route.fullPath) to get precise narrowed types and catch runtime from/route mismatches; use strict: false for genuinely shared components that can't declare a from.

Data loading: Use a route's loader (not component-level useEffect) to fetch data in parallel with route matching. The router ships a built-in stale-while-revalidate cache (staleTime default 0, gcTime default 5 min) keyed on pathname plus loaderDeps (a deterministic function extracting only the search params the loader actually uses). For apps needing mutation APIs, persistence, or a cache shared beyond routing, coordinate an external library (TanStack Query, SWR, etc.) instead: call its prefetch/ensure API from loader without returning the data, and read it in the component via the library's own hook. Always create per-request external clients (e.g. new QueryClient()) inside createRouter/getRouter(), never at module scope, to avoid cross-request leakage on the server.

Search params are typed state, not strings: Validate every route's search params with validateSearch (ideally via a schema library adapter: Zod, Valibot, ArkType, Effect/Schema), preferring .catch()-style fallbacks over .default()-only so malformed URLs degrade gracefully. Read with Route.useSearch() (or useSearch({ from, strict: false }) outside a route's own component). Use search.middlewares (retainSearchParams, stripSearchParams, or custom) for cross-cutting behavior applied to every generated link, instead of repeating logic at each call site.

Navigation model: Every navigation API (Link, useNavigate, <Navigate>, router.navigate) shares the same from/to + params/search/hash/state shape (ToOptions/NavigateOptions/LinkOptions). Prefer <Link> for anything user-clickable (real <a href>, cmd/ctrl-click support, active-state styling); reserve useNavigate/router.navigate for side-effect-driven navigation. Wrap reusable navigation option objects in linkOptions() (not bare object literals) to catch type errors at definition time; wrap custom Link-like components with createLink() to keep full type safety and preload="intent" support.

Flow control via throwables: redirect() and notFound() are thrown (typically from beforeLoad/loader) to short-circuit rendering, mirroring each other's API (isRedirect/isNotFound). Guard an entire route subtree once, on the shared parent's beforeLoad (which always runs before any child's beforeLoad), rather than repeating checks per leaf route. Prefer throwing notFound() from loader over components, to keep loader data typed and avoid flicker. If using typescript-eslint's type-checked rulesets, allowlist Redirect/NotFoundError in only-throw-error rather than disabling it.

Router context for dependency injection: Type it with createRootRouteWithContext<T>(), supply initial values via createRouter({ context }), and extend it per-subtree by returning fields from a route's beforeLoad (merges into that route and its descendants only). Since hooks can't run inside beforeLoad/loader, bridge React-hook-derived values (like auth state) in by calling the hook in a component and passing the result through <RouterProvider context={...}>.

Performance levers: Enable autoCodeSplitting: true (or manual .lazy.tsx files) to split non-critical route config (component, errorComponent, pendingComponent, notFoundComponent) out of the main bundle, never split loader without strong reason since it adds a network round-trip before data fetching starts. Set defaultPreload: 'intent' for the highest-value, lowest-effort navigation-speed win. Use select on router-state hooks (useSearch, useRouterState) to subscribe to narrow state slices, pairing with structuralSharing: true when select computes a fresh object each call.


Chapter Index

Getting Started

#TitleKey Concepts
ch001OverviewInferred TypeScript, first-class search params, built-in cache
ch002Quick Start@tanstack/cli create --router-only, file vs code-based routing
ch003DevtoolsTanStackRouterDevtools, Floating/Fixed/Embedded modes
ch004Decisions on DXgetParentRoute, Register module declaration, no JSX routes
ch005Comparisonvs. React Router DOM and Next.js feature matrix
ch006FAQrouteTree.gen.ts commit policy, root route rendering

Installation Guides

#TitleKey Concepts
ch007Manual Installation__root.tsx, createRouter, RouterProvider
ch008With VitetanstackRouter Vite plugin, ignore-file config
ch009With RspackRsbuild tools.rspack.plugins, Solid + Babel
ch010With Webpack@tanstack/router-plugin/webpack
ch011With Esbuildesbuild.context, manual dev/build/watch script
ch012With Router CLItsr generate/tsr watch, tsr.config.json
ch013Migrate from React RouterLink/useNavigate/useParams conversion
ch014Migrate from React LocationRoute file recreation, module declaration

Core Routing

#TitleKey Concepts
ch015Routing ConceptsIndex/dynamic/splat/layout/pathless/non-nested routes
ch016Route TreesRoute tree = component tree, flat/directory/mixed styles
ch017Route MatchingAutomatic specificity sorting, precedence order
ch018File-Based RoutingDirectory vs flat routes, bundler integration
ch019Virtual File RoutesrootRoute/route/layout/physical, __virtual.ts
ch020Code-Based RoutingcreateRoute, addChildren, not recommended default
ch021File Naming Conventions__root.tsx, ., $, _, -, (folder), [x] tokens
ch022URL RewritesInput/output rewrites, location.publicHref, composeRewrites

Navigation & URL State

#TitleKey Concepts
ch023Navigationfrom/to, Link, useNavigate, useMatchRoute
ch024Link OptionslinkOptions(), type-checked reusable nav objects
ch025Custom LinkcreateLink, UI library integration
ch026Path Params$param, params.parse/stringify, prefix/suffix params
ch027Search ParamsvalidateSearch, schema adapters, search middlewares
ch028Custom Search Param SerializationparseSearchWith/stringifySearchWith, idempotency
ch029Route Maskingmask option, createRouteMask, unmaskOnReload
ch030Navigation BlockinguseBlocker, withResolver, enableBeforeUnload
ch031History TypescreateBrowserHistory/createHashHistory/createMemoryHistory
ch032Scroll RestorationscrollRestoration: true, useElementScrollRestoration
ch033Internationalization (i18n){-$locale}, rewrite option, Paraglide integration

Data & Rendering

#TitleKey Concepts
ch034Code SplittingCritical vs non-critical config, .lazy.tsx, getRouteApi
ch035Automatic Code SplittingcodeSplitGroupings, splitBehavior, defaultBehavior
ch036Data Loadingloader, loaderDeps, staleTime, gcTime, beforeLoad
ch037Deferred Data LoadingUnawaited promises, Await, streaming SSR
ch038External Data LoadingqueryOptions, dehydrate/hydrate/Wrap, per-request stores
ch039Data Mutationsrouter.invalidate(), mutation keys, router.subscribe
ch040PreloadingIntent/viewport/render strategies, preloadStaleTime
ch041Document Head Managementhead option, <HeadContent />, ScriptOnce
ch042SSRStreaming vs non-streaming, createRequestHandler, RouterClient
ch043Render OptimizationsStructural sharing, select, structuralSharing

Router Configuration

#TitleKey Concepts
ch044Creating a RoutercreateRouter, Register declaration merging
ch045Outlets<Outlet />, implicit outlet, root layout pattern
ch046Router Eventsrouter.subscribe, onResolved, onRendered
ch047Type Safetyfrom hint, strict: false, TS performance narrowing
ch048Type UtilitiesValidateLinkOptions, double-overload pattern
ch049Router ContextcreateRootRouteWithContext, context merging, DI
ch050Not Found ErrorsnotFound(), notFoundComponent, notFoundMode
ch051Authenticated RoutesbeforeLoad auth middleware, redirect-based protection
ch052Static Route DatastaticData, useMatches(), breadcrumbs

Integrations

#TitleKey Concepts
ch053TanStack Query IntegrationsetupRouterSsrQueryIntegration, useSuspenseQuery

ESLint

#TitleKey Concepts
ch054ESLint Plugin Routerflat/recommended, only-throw-error interop
ch055create-route Property Order RuleProperty inference order, autofixable

API

#TitleKey Concepts
ch056Router API ReferenceFunctions, components, hooks, types index
ch057File-Based Routing API ReferenceroutesDirectory, routeToken, addExtensions

Topic Index

  • Auth guarding → ch051, ch049, ch050
  • Await component → ch037, ch056
  • beforeLoad → ch036, ch049, ch050, ch051
  • Bundler integration (Vite/Rspack/Webpack/Esbuild) → ch008, ch009, ch010, ch011
  • Code splitting → ch034, ch035
  • createLink → ch025
  • createRouter → ch044, ch056
  • Deferred data / streaming → ch037, ch042
  • Devtools → ch003
  • ESLint rules → ch054, ch055
  • File naming conventions → ch021, ch015, ch018
  • History (browser/hash/memory) → ch031
  • i18n / locale routing → ch033, ch026, ch022
  • Link / navigation APIs → ch023, ch024, ch025
  • Loader caching (staleTime/gcTime) → ch036, ch040
  • Migration (React Router / React Location) → ch013, ch014
  • Not found errors → ch050
  • Outlets → ch045
  • Path params → ch026
  • Preloading → ch040
  • Redirects → ch051, ch056
  • Render optimization / select → ch043
  • Route context (dependency injection) → ch049
  • Route masking → ch029
  • Route matching / specificity → ch017
  • Route trees → ch016
  • Router events (router.subscribe) → ch046
  • Scroll restoration → ch032
  • Search params → ch027, ch028
  • SSR → ch042
  • Static route data → ch052
  • TanStack Query integration → ch053, ch038
  • Type safety / from hint → ch047, ch048
  • URL rewrites → ch022
  • Virtual file routes → ch019

Supporting Files