Skip to main content
Back to module
React Fundamentals · Building an App

Routing basics

Reading56mLesson 1 of 3 in this module

Map URLs to pages with React Router or Next.js file-based routing, including dynamic segments and links.

Why it matters

Real apps have many screens: a home page, a product page, a settings page. Users expect each one to have its own URL that they can bookmark, share and reach with the back button. Routing maps URLs to the components that render them. React itself has no router, so you will use a library (React Router) or a framework (Next.js) for it.

Multi-page apps and single-page apps

In a traditional site, every link asks the server for a new HTML page. In a single-page application (SPA) the browser loads the app once; when you click a link, JavaScript changes the URL with the History API and swaps the components on screen without a full reload. That is faster for users and keeps state (such as a half-filled form in a sidebar) alive.

The cost: the app must handle URLs itself, and the server must send the app's HTML for any path the user might load directly (/products/42), or refreshing that page gives a 404. Hosts such as Netlify and Vercel have settings for this.

React Router

React Router is the most widely used routing library for client-side React apps. A typical setup (version 6 or 7, "declarative" mode):

import { BrowserRouter, Routes, Route, Link, useParams } from "react-router";

function App() {
  return (
    <BrowserRouter>
      <nav>
        <Link to="/">Home</Link> <Link to="/products">Products</Link>
      </nav>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/products" element={<ProductList />} />
        <Route path="/products/:id" element={<ProductPage />} />
        <Route path="*" element={<NotFound />} />
      </Routes>
    </BrowserRouter>
  );
}

function ProductPage() {
  const { id } = useParams(); // "42" for /products/42
  return <h1>Product {id}</h1>;
}

(In version 6 the imports come from react-router-dom; version 7 merged it into react-router. Check the docs for the version your project uses.)

The ideas to know:

  • <Route path element> maps a URL pattern to a component.
  • Dynamic segments such as :id match any value and are read with useParams(). Params are always strings: convert with Number(id) if needed.
  • path="*" is a catch-all for a "not found" page.
  • <Link to> renders a real <a> tag but navigates without reloading. Do not use a plain <a href> for in-app links, or the whole app reloads and loses state.
  • useNavigate() navigates from code, for example after saving a form: navigate("/products/42").
  • Nested routes render inside a parent layout with <Outlet />, so a dashboard sidebar stays while the main area changes.
  • Query strings (/search?q=react) are read with useSearchParams(). Keeping filters in the URL makes them shareable.

File-based routing in Next.js

Frameworks such as Next.js build the routes from your file names instead of a route list. With the Pages Router:

pages/
  index.tsx              ->  /
  about.tsx              ->  /about
  products/index.tsx     ->  /products
  products/[id].tsx      ->  /products/42, /products/abc
  404.tsx                ->  custom not-found page

Each file exports a React component as its default export. Square brackets mark a dynamic segment; the page reads it with useRouter().query.id (or receives it in data-loading functions). Links use next/link:

import Link from "next/link";

<Link href="/products/42">Widget</Link>

Next.js also offers the newer App Router (app/ folder, with page.tsx files and nested layout.tsx files). The concepts are the same: a URL maps to a component, with dynamic segments and shared layouts. Frameworks add server rendering, so each URL can arrive as ready-made HTML, which helps speed and search engines.

Protecting routes

Some pages need a signed-in user. In an SPA a route component can check the user (often from context) and redirect to the login page. Remember that this only hides the screen: the API must still check permissions on every request, because anyone can call it directly.

Accessibility and polish

  • Give each page a unique <title> and one <h1>.
  • After navigation, move focus to the main heading or content so screen-reader users know the page changed.
  • Show a loading state while route data loads, and a helpful 404 page for unknown URLs.

Common mistakes

  • Using <a href> for internal links in an SPA and losing state on every click.
  • Forgetting that URL params are strings.
  • Deploying an SPA without a fallback rule, so deep links 404 on refresh.
  • Treating client-side route guards as security.

Recap

  • Routing maps URLs to components; SPAs change the URL without full reloads.
  • React Router: Routes/Route, :param with useParams, Link, useNavigate, nested layouts with Outlet.
  • Next.js derives routes from files; [id] marks a dynamic segment.
  • Real protection lives on the server; client-side guards are for user experience.

Try it

Open the Do tab and take the quiz on matching URLs to routes and choosing the right navigation tools.

Also in this lesson: