# Introduction to React Router

> Learn the current React Router declarative API with BrowserRouter, Routes, Route, Link, URL parameters, and programmatic navigation.

Author: [Flavio Copes](https://flaviocopes.com/about/) | Published: 2018-03-28 | Updated: 2026-07-18 | Topics: [React](https://flaviocopes.com/tags/react/) | Canonical: https://flaviocopes.com/react-router/

React Router connects the browser URL to a React interface. It lets a single-page application render a different component for each path while keeping normal links, browser history, and back and forward navigation.

This guide uses React Router's **Declarative mode**, the smallest setup for adding client-side routing to an existing React application.

React Router also provides Data mode and Framework mode for applications that need route loaders, actions, code splitting, and other framework features.

## Install React Router

Install the current package:

```bash
npm install react-router
```

Older projects may import browser APIs from `react-router-dom`. Current React Router documentation uses `react-router` for new declarative applications.

## Add BrowserRouter

Wrap the application with `BrowserRouter` at the root:

```jsx
import { StrictMode } from 'react'
import { createRoot } from 'react-dom/client'
import { BrowserRouter } from 'react-router'
import App from './App.jsx'

createRoot(document.getElementById('root')).render(
  <StrictMode>
    <BrowserRouter>
      <App />
    </BrowserRouter>
  </StrictMode>,
)
```

`BrowserRouter` uses the browser History API to keep the interface and URL in sync.

## Define routes

Put `Route` elements inside `Routes`:

```jsx
import { Route, Routes } from 'react-router'
import Home from './pages/Home.jsx'
import About from './pages/About.jsx'
import NotFound from './pages/NotFound.jsx'

export default function App() {
  return (
    <Routes>
      <Route path="/" element={<Home />} />
      <Route path="/about" element={<About />} />
      <Route path="*" element={<NotFound />} />
    </Routes>
  )
}
```

`Routes` chooses the best matching route for the current URL. The `element` prop contains the React element to render.

You do not need the old `exact` prop. Current route matching handles this without it.

## Navigate with Link

Use `Link` for normal navigation inside the application:

```jsx
import { Link } from 'react-router'

export default function Navigation() {
  return (
    <nav>
      <Link to="/">Home</Link>
      {' '}
      <Link to="/about">About</Link>
    </nav>
  )
}
```

`Link` renders an accessible link and prevents a full document reload for routes handled by the application.

Use a regular `<a>` element when linking to another site or to a download that should trigger normal browser navigation.

`NavLink` works like `Link` but also exposes whether the link is active or pending:

```jsx
import { NavLink } from 'react-router'

<NavLink
  to="/about"
  className={({ isActive }) => isActive ? 'active' : undefined}
>
  About
</NavLink>
```

## Read URL parameters

A path segment beginning with `:` is dynamic:

```jsx
<Route path="/posts/:postId" element={<Post />} />
```

Read the value with `useParams()`:

```jsx
import { useParams } from 'react-router'

export default function Post() {
  const { postId } = useParams()

  return <h1>Post {postId}</h1>
}
```

Visiting `/posts/42` gives `postId` the string value `"42"`.

URL values are user input. Validate a parameter before using it in a query or sending it to a server.

## Create nested routes

Routes can mirror a layout hierarchy:

```jsx
import { Outlet, Route, Routes } from 'react-router'

function DashboardLayout() {
  return (
    <>
      <h1>Dashboard</h1>
      <Outlet />
    </>
  )
}

function App() {
  return (
    <Routes>
      <Route path="/dashboard" element={<DashboardLayout />}>
        <Route index element={<DashboardHome />} />
        <Route path="settings" element={<Settings />} />
      </Route>
    </Routes>
  )
}
```

The child route renders where the parent places `<Outlet />`.

The index route matches `/dashboard`. The settings route matches `/dashboard/settings`.

## Read the current location

`useLocation()` returns information about the current location:

```jsx
import { useLocation } from 'react-router'

function CurrentPath() {
  const location = useLocation()

  return <p>Current path: {location.pathname}</p>
}
```

The object also contains `search`, `hash`, `state`, and a location `key`.

Use `URLSearchParams` to read a small number of query-string values, or React Router's `useSearchParams()` hook when you also need to update them.

## Navigate from code

Use `useNavigate()` when navigation happens after an action, such as completing a form:

```jsx
import { useNavigate } from 'react-router'

function LoginForm() {
  const navigate = useNavigate()

  async function handleSubmit(event) {
    event.preventDefault()

    const success = await logIn()

    if (success) {
      navigate('/dashboard', { replace: true })
    }
  }

  return <form onSubmit={handleSubmit}>{/* fields */}</form>
}
```

Prefer `Link` or `NavLink` when the user is simply choosing where to go. Links provide better keyboard, accessibility, and browser behavior.

## Configure the web server

`BrowserRouter` creates URLs such as `/about`, but the browser can also request that URL directly after a refresh.

Your hosting server must serve the application's HTML entry file for client-side routes that do not match a real static file. Without that fallback, a direct visit to `/about` may return a 404 even though in-app navigation works.

See the official React Router guides for [Declarative mode installation](https://reactrouter.com/start/declarative/installation), [routing](https://reactrouter.com/start/declarative/routing), [navigation](https://reactrouter.com/start/declarative/navigating), and [the available modes](https://reactrouter.com/start/modes).
