Skip to main content

React Components

React components for rendering routes, handling errors, and managing navigation.

RouterProvider

The root component that provides router context to your application.
import { RouterProvider } from '@tanstack/react-router'
import { router } from './router'

function App() {
  return <RouterProvider router={router} />
}

Props

router
Router
required
The router instance.
defaultComponent
RouteComponent
Fallback component when a route has no component.
defaultErrorComponent
ErrorRouteComponent
Default error component for all routes.
defaultPendingComponent
RouteComponent
Default loading component for all routes.
context
any
Additional context to merge with router context.

Outlet

Render child route components.
import { Outlet } from '@tanstack/react-router'

function Layout() {
  return (
    <div>
      <Header />
      <main>
        <Outlet />
      </main>
      <Footer />
    </div>
  )
}

Match

Render a specific route match.
import { Match } from '@tanstack/react-router'

function CustomLayout() {
  return (
    <div>
      <Sidebar />
      <Match from="/posts" component={PostsLayout} />
    </div>
  )
}

Props

from
string
required
Route ID to match.
component
RouteComponent
Component to render.
errorComponent
ErrorRouteComponent
Error component.
pendingComponent
RouteComponent
Loading component.

MatchRoute

Conditionally render based on route matching.
import { MatchRoute } from '@tanstack/react-router'

function Navigation() {
  return (
    <nav>
      <Link to="/">Home</Link>
      
      <MatchRoute to="/admin">
        {(match) => match && <AdminMenu />}
      </MatchRoute>
    </nav>
  )
}

Props

to
string
required
Path to match.
params
boolean | Record<string, any>
Match with specific params.
pending
boolean
Match pending routes.
caseSensitive
boolean
Case-sensitive matching.
children
(match: RouteMatch | false) => ReactNode
required
Render function.

Matches

Render all current route matches.
import { Matches } from '@tanstack/react-router'

function App() {
  return (
    <div>
      <Header />
      <Matches />
    </div>
  )
}
Declarative navigation component.
import { Navigate } from '@tanstack/react-router'

function ProtectedRoute({ children }) {
  const { user } = useAuth()
  
  if (!user) {
    return <Navigate to="/login" replace />
  }
  
  return children
}

Props

to
string
required
Destination path.
params
Record<string, any>
Path parameters.
Search parameters.
hash
string
URL hash.
replace
boolean
Replace history entry.
resetScroll
boolean
Reset scroll position.
Navigation link component.
import { Link } from '@tanstack/react-router'

<Link to="/posts">View Posts</Link>
<Link to="/posts/$postId" params={{ postId: '123' }}>Post 123</Link>
See Link API for full documentation.

CatchBoundary

Error boundary for routes.
import { CatchBoundary } from '@tanstack/react-router'

function ErrorBoundary() {
  return (
    <CatchBoundary
      getResetKey={() => 'reset'}
      onCatch={(error) => console.error(error)}
      errorComponent={({ error, reset }) => (
        <div>
          <h1>Something went wrong</h1>
          <pre>{error.message}</pre>
          <button onClick={reset}>Try Again</button>
        </div>
      )}
    >
      <MyComponent />
    </CatchBoundary>
  )
}

Props

children
ReactNode
required
Children to wrap.
errorComponent
ErrorRouteComponent
Component to render on error.
getResetKey
() => string
Function to generate reset key.
onCatch
(error: Error, errorInfo: ErrorInfo) => void
Error handler callback.

ErrorComponent

Default error component.
import { ErrorComponent } from '@tanstack/react-router'

function MyErrorComponent({ error, reset }) {
  return (
    <div>
      <ErrorComponent error={error} />
      <button onClick={reset}>Reset</button>
    </div>
  )
}

Props

error
Error
required
The error object.

ScrollRestoration

Restore scroll position on navigation.
import { ScrollRestoration } from '@tanstack/react-router'

function RootLayout() {
  return (
    <div>
      <ScrollRestoration />
      <Outlet />
    </div>
  )
}

Props

getKey
(location) => string
Function to generate scroll restoration key.
<ScrollRestoration 
  getKey={(location) => location.pathname}
/>

Block

Block navigation with confirmation (declarative version of useBlocker).
import { Block } from '@tanstack/react-router'

function EditForm() {
  const [isDirty, setIsDirty] = useState(false)
  
  return (
    <div>
      {isDirty && (
        <Block
          blockerFn={async () => {
            return window.confirm('Discard changes?')
          }}
          enableBeforeUnload
        />
      )}
      
      <form onChange={() => setIsDirty(true)}>...</form>
    </div>
  )
}

Props

blockerFn
BlockerFn
required
Function to determine if navigation should be blocked.
enableBeforeUnload
boolean
Enable browser beforeunload warning.

Await

Await deferred data in Suspense boundaries.
import { Await, defer } from '@tanstack/react-router'
import { Suspense } from 'react'

const route = createRoute({
  loader: async () => {
    const critical = await fetchCriticalData()
    const deferred = defer(fetchDeferredData())
    
    return { critical, deferred }
  },
  component: () => {
    const { critical, deferred } = route.useLoaderData()
    
    return (
      <div>
        <h1>{critical.title}</h1>
        
        <Suspense fallback={<div>Loading...</div>}>
          <Await promise={deferred}>
            {(data) => <Details data={data} />}
          </Await>
        </Suspense>
      </div>
    )
  }
})

Props

promise
Promise<T>
required
The deferred promise to await.
children
(data: T) => ReactNode
required
Render function receiving resolved data.

ClientOnly

Render children only on the client.
import { ClientOnly } from '@tanstack/react-router'

function MyComponent() {
  return (
    <div>
      <h1>Server and Client</h1>
      
      <ClientOnly fallback={<div>Loading...</div>}>
        {() => <BrowserOnlyComponent />}
      </ClientOnly>
    </div>
  )
}

Props

children
() => ReactNode
required
Function returning client-only content.
fallback
ReactNode
Content to render on the server.

NotFoundRoute

Handle 404 pages.
import { NotFoundRoute } from '@tanstack/react-router'

const notFoundRoute = new NotFoundRoute({
  getParentRoute: () => rootRoute,
  component: () => (
    <div>
      <h1>404 - Page Not Found</h1>
      <Link to="/">Go Home</Link>
    </div>
  )
})

CatchNotFound

Catch not found errors.
import { CatchNotFound, DefaultGlobalNotFound } from '@tanstack/react-router'

function App() {
  return (
    <CatchNotFound fallback={<DefaultGlobalNotFound />}>
      <RouterProvider router={router} />
    </CatchNotFound>
  )
}

Scripts

Render route scripts (for SSR).
import { Scripts } from '@tanstack/react-router'

function RootDocument() {
  return (
    <html>
      <head>...</head>
      <body>
        <Outlet />
        <Scripts />
      </body>
    </html>
  )
}

Examples

Complete Layout

import { 
  Outlet, 
  ScrollRestoration,
  Scripts 
} from '@tanstack/react-router'

function RootLayout() {
  return (
    <html>
      <head>
        <meta charSet="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
      </head>
      <body>
        <div className="app">
          <Header />
          <main>
            <Outlet />
          </main>
          <Footer />
        </div>
        <ScrollRestoration />
        <Scripts />
      </body>
    </html>
  )
}

Conditional Rendering

import { MatchRoute } from '@tanstack/react-router'

function Sidebar() {
  return (
    <aside>
      <MatchRoute to="/admin" fuzzy>
        {(match) => match && <AdminMenu />}
      </MatchRoute>
      
      <MatchRoute to="/dashboard" fuzzy>
        {(match) => match && <DashboardMenu />}
      </MatchRoute>
    </aside>
  )
}

Error Handling

import { CatchBoundary, ErrorComponent } from '@tanstack/react-router'

const rootRoute = createRootRoute({
  errorComponent: ({ error, reset }) => (
    <div className="error-page">
      <h1>Application Error</h1>
      <ErrorComponent error={error} />
      <button onClick={reset}>Reset Application</button>
      <Link to="/">Go Home</Link>
    </div>
  ),
  component: RootLayout
})

Deferred Data Loading

import { Await, defer } from '@tanstack/react-router'
import { Suspense } from 'react'

const dashboardRoute = createRoute({
  loader: async () => {
    // Critical data (blocks navigation)
    const user = await fetchUser()
    
    // Deferred data (doesn't block)
    const stats = defer(fetchStats())
    const activity = defer(fetchActivity())
    
    return { user, stats, activity }
  },
  component: () => {
    const { user, stats, activity } = dashboardRoute.useLoaderData()
    
    return (
      <div>
        <h1>Welcome {user.name}</h1>
        
        <div className="grid">
          <Suspense fallback={<StatsLoader />}>
            <Await promise={stats}>
              {(data) => <StatsCard data={data} />}
            </Await>
          </Suspense>
          
          <Suspense fallback={<ActivityLoader />}>
            <Await promise={activity}>
              {(data) => <ActivityFeed data={data} />}
            </Await>
          </Suspense>
        </div>
      </div>
    )
  }
})

Build docs developers (and LLMs) love