Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/tanstack/router/llms.txt

Use this file to discover all available pages before exploring further.

TanStack Router provides a powerful, type-safe routing system that supports both file-based and code-based routing approaches. At its core, the router matches URLs to route definitions, loads data, and renders the appropriate components.

How Routing Works

The router operates by matching the current browser location against a tree of route definitions. Each route can:
  • Define a path pattern to match against
  • Load data before rendering
  • Validate and parse URL parameters
  • Render components with full type safety

Route Trees

Routes are organized in a hierarchical tree structure, where child routes inherit context from their parents:
const rootRoute = createRootRoute()

const indexRoute = createRoute({
  getParentRoute: () => rootRoute,
  path: '/',
})

const aboutRoute = createRoute({
  getParentRoute: () => rootRoute,
  path: '/about',
})

const routeTree = rootRoute.addChildren([indexRoute, aboutRoute])

Creating a Router

The router is created with a route tree and various configuration options:
import { createRouter } from '@tanstack/react-router'

const router = createRouter({
  routeTree,
  defaultPreload: 'intent',
  defaultStaleTime: 5000,
})

Key Router Options

routeTree
AnyRoute
required
The route tree that defines all routes in your application.
basepath
string
default:"'/'"
The base path for the entire router, useful for mounting at a subpath.
history
RouterHistory
Custom history implementation. Defaults to createBrowserHistory().
defaultPreload
false | 'intent' | 'viewport' | 'render'
default:"false"
  • false - No preloading
  • 'intent' - Preload on hover or touch
  • 'viewport' - Preload when in viewport
  • 'render' - Preload when rendered
caseSensitive
boolean
default:"false"
Whether route matching should be case-sensitive.
trailingSlash
'always' | 'never' | 'preserve'
default:"'never'"
How to handle trailing slashes in URLs:
  • 'always' - Add trailing slash if not present
  • 'never' - Remove trailing slash if present
  • 'preserve' - Keep as-is
notFoundMode
'root' | 'fuzzy'
default:"'fuzzy'"
  • 'root' - Show not found at root level
  • 'fuzzy' - Show not found at deepest matching parent

Route Matching

The router uses a sophisticated matching algorithm that:
  1. Parses the pathname into segments
  2. Matches static segments exactly
  3. Extracts path parameters from dynamic segments
  4. Handles wildcards for catch-all routes
  5. Validates search params using validators
  6. Selects the best match when multiple routes could match

Path Patterns

// Static route
path: '/about'

// Path parameter
path: '/posts/$postId'

// Optional parameter
path: '/posts/{-$postId}'

// Wildcard (catch-all)
path: '/files/$'

Router State

The router maintains state that includes:
interface RouterState {
  status: 'pending' | 'idle'
  isLoading: boolean
  isTransitioning: boolean
  location: ParsedLocation
  matches: Array<RouteMatch>
  pendingMatches?: Array<RouteMatch>
  cachedMatches: Array<RouteMatch>
}
Access router state with:
const router = useRouter()
const { location, matches, isLoading } = router.state
When navigating to a new route, the router:
  1. Matches routes against the new URL
  2. Validates search and path params on each matched route
  3. Calls beforeLoad hooks in sequence
  4. Loads data via loader functions in parallel
  5. Updates state and renders components
  6. Handles errors through error boundaries

Router Events

Subscribe to navigation lifecycle events:
router.subscribe('onBeforeLoad', (event) => {
  console.log('Navigating from:', event.fromLocation)
  console.log('Navigating to:', event.toLocation)
})
Available events:
  • onBeforeNavigate - Before URL changes
  • onBeforeLoad - Before data loading starts
  • onLoad - After data loading completes
  • onResolved - After route is resolved
  • onRendered - After components render

Protocol Allowlist

For security, the router validates URL protocols:
const router = createRouter({
  routeTree,
  protocolAllowlist: ['http:', 'https:', 'mailto:', 'tel:'],
})
Absolute URLs with protocols not in the allowlist will be rejected.

Rewriting URLs

Advanced use cases can rewrite URLs between the browser and router:
const router = createRouter({
  routeTree,
  rewrite: {
    input: ({ url }) => {
      // Transform URL before router processes it
      return url
    },
    output: ({ url }) => {
      // Transform URL before committing to history
      return url
    },
  },
})

Best Practices

Enable strict TypeScript settings and use route type helpers for full type safety across params, search, and context.
Organize routes to reflect your UI hierarchy. Child routes inherit context and layouts from parents.
Set defaultPreload: 'intent' to automatically preload routes when users hover over links.
Define errorComponent on routes to catch and display errors in a user-friendly way.

Next Steps

Routes

Learn how to define and configure routes

Navigation

Navigate between routes programmatically

Path Params

Extract and validate path parameters

Search Params

Work with URL search parameters