React Router - Navigation in your SPAs

Hi! Now that we've mastered components and hooks, we're going to tackle navigation in our React applications.

As your app grows, you'll want to have multiple "pages" with different URLs. That's where React Router comes in!


What is routing?

The problem with SPAs

In a Single Page Application (SPA), we technically only have one HTML page. But we still want:

  • Different URLs for each "page" (/home, /about, /profile)
  • The browser's "Back" button to work
  • To be able to share links
  • Good SEO

React Router to the rescue

React Router will allow us to:

  • Associate components with URLs
  • Navigate between pages without reloading
  • Manage browser history
  • Pass parameters in the URLs

Installing React Router

npm install react-router-dom

That's it! React Router DOM is the version for the web (there's also React Router Native for React Native).


Basic Configuration

1. Wrap your app with BrowserRouter

In your main.jsx:

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

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

2. Define routes in App.jsx

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

function App() {
  return (
    <div>
      <nav>
        <a href="/">Home</a>
        <a href="/about">About</a>
        <a href="/contact">Contact</a>
      </nav>

      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
        <Route path="/contact" element={<Contact />} />
        <Route path="*" element={<NotFound />} />
      </Routes>
    </div>
  )
}

export default App

3. Create your page components

// src/pages/Home.jsx
function Home() {
  return (
    <div>
      <h1>🏠 Home</h1>
      <p>Welcome to the home page!</p>
    </div>
  )
}

export default Home

// src/pages/About.jsx
function About() {
  return (
    <div>
      <h1>📖 About</h1>
      <p>Here's our story...</p>
    </div>
  )
}

export default About

The problem with <a href="">

If you use classic HTML links, the entire page reloads with each click. We lose all the advantages of an SPA!

import { Link } from 'react-router-dom'

function Navigation() {
  return (
    <nav>
      <Link to="/">Home</Link>
      <Link to="/about">About</Link>
      <Link to="/contact">Contact</Link>
    </nav>
  )
}

NavLink allows you to style the current page's link:

import { NavLink } from 'react-router-dom'

function Navigation() {
  return (
    <nav>
      <NavLink
        to="/"
        className={({ isActive }) => isActive ? 'active-link' : ''}
      >
        Home
      </NavLink>
      <NavLink
        to="/about"
        className={({ isActive }) => isActive ? 'active-link' : ''}
      >
        About
      </NavLink>
    </nav>
  )
}

Next.js App Router (for Next.js projects)

// app/page.js (Next.js 13+)
export default function HomePage() {
  return <h1>Home Page</h1>
}

// app/blog/page.js
export default function BlogPage() {
  return <h1>Blog</h1>
}

// Navigation in Next.js
import Link from 'next/link'

function Navigation() {
  return (
    <nav>
      <Link href="/">Home</Link>
      <Link href="/blog">Blog</Link>
    </nav>
  )
}

Resources for further learning