Last updated: 2026-05-06

Basic routing with React Router

React Router is a library that lets you navigate between different "pages" (components) in a single-page React app without reloading the browser. It introduces routes — mappings between URLs and components — keeping your app feeling like a multi-page website while staying a single-page application (SPA).


Installation

React Router is a third-party library and must be installed before use:

npm install react-router-dom

Key Concepts

ConceptDescription
BrowserRouterWraps your entire app to enable routing. Uses the browser's history API to keep the URL in sync with the UI.
RoutesA container that holds all your Route definitions. Renders only the first route that matches the current URL.
RouteMaps a URL path to a component. When the URL matches the path, the component is rendered.
LinkNavigates to a route without reloading the page. Use instead of <a> tags in a React SPA.
NavLinkLike Link, but automatically applies an active style or class when its route is the current URL. Ideal for navigation menus.
useNavigateA hook for programmatic navigation — redirecting the user from inside a function rather than from a click on a link.
useParamsA hook that reads dynamic parameters from the current URL (e.g. the id in /user/:id).

Basic Setup

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

function Home() {
  return <h2>Home Page</h2>;
}

function About() {
  return <h2>About Page</h2>;
}

function App() {
  return (
    <BrowserRouter>
      <nav>
        <Link to="/">Home</Link> | <Link to="/about">About</Link>
      </nav>

      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
      </Routes>
    </BrowserRouter>
  );
}

export default App;

How it works:

  • <BrowserRouter> enables routing for the entire app.
  • <Link to="/about"> navigates without a full page reload.
  • <Route path="/about" element={<About />} /> renders the About component when the URL matches /about.

NavLink — Active Navigation Links

NavLink works like Link but automatically applies an active class to the link when its route matches the current URL. This makes it the preferred choice for navigation menus where you want to highlight the current page.

import { NavLink } from "react-router-dom";

function Nav() {
  return (
    <nav>
      <NavLink to="/" style={({ isActive }) => ({ fontWeight: isActive ? "bold" : "normal" })}>
        Home
      </NavLink>
      <NavLink to="/about" style={({ isActive }) => ({ fontWeight: isActive ? "bold" : "normal" })}>
        About
      </NavLink>
    </nav>
  );
}

The isActive boolean is provided automatically by React Router and reflects whether the link's path matches the current URL.


Dynamic Routes and useParams

Dynamic routes use a colon prefix (:param) to define a variable segment in the URL. This is how you build pages like user profiles, product pages, or blog posts — where the content changes based on an ID in the URL.

import { Routes, Route } from "react-router-dom";

function App() {
  return (
    <Routes>
      <Route path="/user/:id" element={<UserProfile />} />
    </Routes>
  );
}

Inside the UserProfile component, use useParams to read the dynamic value from the URL:

import { useParams } from "react-router-dom";

function UserProfile() {
  const { id } = useParams();

  return <h2>Viewing profile for user: {id}</h2>;
}

If the user visits /user/42, id will be "42". If they visit /user/wariz, id will be "wariz".


Programmatic Navigation with useNavigate

Link and NavLink handle navigation triggered by user clicks. But sometimes you need to navigate programmatically — after a form is submitted, after a login succeeds, or after an item is deleted. useNavigate is the hook for this.

import { useNavigate } from "react-router-dom";

function LoginForm() {
  const navigate = useNavigate();

  function handleSubmit() {
    // perform login logic...
    navigate("/dashboard"); // redirect after login
  }

  return (
    <button onClick={handleSubmit}>Log In</button>
  );
}

You can also navigate backwards using navigate(-1), which is equivalent to hitting the browser's back button.


404 — Catch-All Route

Every real application needs a fallback for URLs that don't match any defined route. Use path="*" as the last route in your Routes block to catch all unmatched paths:

function NotFound() {
  return <h2>404 — Page Not Found</h2>;
}

function App() {
  return (
    <BrowserRouter>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
        <Route path="*" element={<NotFound />} /> {/* Catch-all */}
      </Routes>
    </BrowserRouter>
  );
}

The * route must always be last — React Router matches routes in order and renders the first match.