React Router — Routes, Links and Layouts
BeginnerRoutes map URLs to components, Link navigates without a reload, and nested routes let a layout stay mounted while only the inner part changes.
Overview
React has no router, so a single-page app needs one, and React Router is what most teams use outside Next.js. The mechanics sit on the History API from the JavaScript track: the router pushes a URL, matches it against your route definitions, and renders the matching component. The part worth learning properly is nesting, because it maps directly onto how applications are actually laid out — a shell with navigation that stays put while the content area changes, without re-mounting the shell on every navigation.
Defining Routes
A route tree, with layouts as parent routes.
const router = createBrowserRouter([
{
path: '/',
element: <RootLayout />, // header, nav, footer — stays mounted
errorElement: <ErrorPage />,
children: [
{ index: true, element: <Home /> },
{ path: 'problems', element: <ProblemList /> },
{ path: 'problems/:slug', element: <ProblemDetail /> },
{
path: 'account',
element: <AccountLayout />, // a nested layout with its own tabs
children: [
{ index: true, element: <Profile /> },
{ path: 'billing', element: <Billing /> },
],
},
{ path: '*', element: <NotFound /> }, // 404, always include one
],
},
])
<RouterProvider router={router} />
// The layout renders <Outlet /> where the child route goes
function RootLayout() {
return <><Header /><main><Outlet /></main><Footer /></>
}Navigating
Link for user navigation, navigate for programmatic. Never an anchor to an internal route.
<Link to="/problems">Problems</Link>
<Link to={`/problems/${slug}`} state={{ from: 'list' }}>Open</Link>
// NavLink knows whether it is the current route
<NavLink to="/problems" className={({ isActive }) => isActive ? 'on' : ''}>
// A plain <a href="/problems"> triggers a full page reload —
// losing all state and re-downloading the app.
// Programmatic navigation, after an action
const navigate = useNavigate()
await createProblem(values)
navigate(`/problems/${created.slug}`)
navigate(-1) // back
navigate('/login', { replace: true }) // no history entry
// replace matters after a redirect: without it, pressing back
// returns the user to the page that just bounced them.
// Reading where you are
const { slug } = useParams()
const location = useLocation() // pathname, search, stateData and Errors per Route
Loaders fetch before the route renders; errorElement catches what fails.
{
path: 'problems/:slug',
element: <ProblemDetail />,
loader: ({ params, request }) =>
getProblem(params.slug, { signal: request.signal }),
errorElement: <RouteError />,
}
function ProblemDetail() {
const problem = useLoaderData() // already resolved — no loading state
return <Article problem={problem} />
}
// Loaders fetch in parallel with the route transition rather than
// after it, which removes the render-then-fetch waterfall.
// errorElement catches a thrown loader error or a render error in
// that subtree, so one broken route does not blank the whole app.
const error = useRouteError()
// Many teams use loaders for the initial fetch and TanStack Query
// for everything after — the two compose, and the query cache can
// be seeded from the loader.Key Points to Remember
- 1Nested routes keep a layout mounted while only the inner Outlet changes on navigation
- 2Link and NavLink navigate client-side; a plain anchor to an internal route reloads the whole app
- 3navigate(path, { replace: true }) avoids a history entry, which matters after a redirect
- 4Always define a catch-all route so an unknown URL renders a real 404 page
- 5Loaders fetch during the transition rather than after render, and errorElement contains failures to one subtree
Interview Questions
Sign in to ask AriaWhat happens if you use a plain <a> tag to link between routes in a single-page app?
What is an Outlet and why do nested routes matter?
When would you navigate with replace: true?
Ask Aria about React Router — Routes, Links and Layouts
Your personal AI tutor — ask anything about this concept
Revision Status
Personal Notes
Sign in to save personal notes for this topic.
Discussion
Sign in to join the discussion.