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
Fallback component when a route has no component.
Default error component for all routes.
Default loading component for all routes.
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
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
params
boolean | Record<string, any>
Match with specific params.
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>
)
}
Navigate
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
Link
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
Component to render on error.
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
Restore scroll position on navigation.
import { ScrollRestoration } from '@tanstack/react-router'
function RootLayout() {
return (
<div>
<ScrollRestoration />
<Outlet />
</div>
)
}
Props
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
Function to determine if navigation should be blocked.
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
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
Function returning client-only content.
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>
)
}
})