Skip to content

Client-Side Routing

intermediate2 min read
  • React
  • Next.js

How a single-page app maps URLs to views and swaps them in the browser without a full page reload, keeping the address bar and navigation in sync.

Prerequisites

  • React components and composition (see Related Topics)

What you'll understand

  • What client-side routing is and how it differs from traditional navigation
  • How URLs map to components
  • Why routing enables a single-page application

Explanation

Client-side routing is how a single-page application (SPA) shows different views for different URLs without asking the server for a whole new page each time. Traditionally, clicking a link makes the browser throw away the current page and load a fresh one. A router intercepts that navigation, updates the URL, and swaps the displayed components in place, so the app feels instant.

A router works by mapping each route (a URL path) to a component. When the path is /dashboard the router renders the dashboard view; when it is /users/42 it renders the user view and hands it the id from the URL. The router keeps the browser address bar, the history (so back and forward work), and the rendered UI all in sync with one another.

This is what makes an SPA possible: one initial page load, then routing handles everything after. Frameworks provide this differently, React Router matches routes you declare in code, while Next.js derives routes from the file system, but the idea is the same. Because navigation no longer reloads the page, routing pairs naturally with on-demand data fetching and code splitting (see Related Topics), which load each view’s data and code only when its route is visited.

Examples

With React Router, you declare which component renders for each path, and a parameter is read from the URL:

<Routes>
  <Route path="/dashboard" element={<Dashboard />} />
  <Route path="/users/:id" element={<UserProfile />} />
</Routes>

Navigation uses a link component that updates the route without reloading the page:

<Link to="/dashboard">Dashboard</Link> // no full page reload

Common mistakes

  • Using a plain anchor tag for internal navigation, forcing a full page reload.
  • Forgetting to configure the server to serve the app for unknown paths, breaking refresh on deep links.
  • Duplicating the URL state in component state instead of reading it from the route.
  • Not handling an unmatched route with a not-found view.

Best practices

  • Map each URL to a single component and read parameters from the route.
  • Use the framework link/navigation component instead of raw anchors for internal links.
  • Provide a catch-all not-found route.
  • Combine routing with per-route data fetching and code splitting (see Related Topics).

Further reading

Related topics