Building a Multi-Page App with Navigation and Theming

As your application grows beyond a single view, managing multiple pages and providing consistent theming becomes critical. This module focuses on how to build a multi-page React application using routing and implement a flexible theming system using tools like Tailwind CSS, Context API, and CSS Variables.

We’ll guide you through setting up routes, creating page layouts, and building a dark/light theme toggle for a seamless user experience.


Table of Contents

  1. Why Multi-Page Apps in React?
  2. Setting Up Page Routes with React Router
  3. Creating a Navigation Bar
  4. Structuring Pages and Layouts
  5. Theme Management Strategies
  6. Implementing Light and Dark Themes
  7. Using Tailwind CSS for Theming
  8. Using Context API for Theme Toggle
  9. Adding Transitions and Enhancing UX
  10. Best Practices for Navigation and Theming
  11. Conclusion

1. Why Multi-Page Apps in React?

While Single Page Applications (SPAs) are powerful, structuring your app into distinct pages improves maintainability, SEO (especially with frameworks like Next.js), and user experience. A multi-page structure with reusable layouts makes large applications easier to scale and organize.


2. Setting Up Page Routes with React Router

Install React Router:

bashCopyEditnpm install react-router-dom

Basic setup:

jsxCopyEditimport { BrowserRouter, Routes, Route } from 'react-router-dom';
import Home from './pages/Home';
import About from './pages/About';

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

3. Creating a Navigation Bar

Add a Navbar component that links to various pages:

jsxCopyEditimport { Link } from 'react-router-dom';

function Navbar() {
  return (
    <nav className="flex space-x-4 bg-gray-200 p-4">
      <Link to="/">Home</Link>
      <Link to="/about">About</Link>
    </nav>
  );
}

4. Structuring Pages and Layouts

Organize your pages inside a pages/ directory, and extract common layout elements (like headers and footers) into a Layout component:

jsxCopyEditfunction Layout({ children }) {
  return (
    <>
      <Navbar />
      <main>{children}</main>
      <footer>© 2025</footer>
    </>
  );
}

Use this layout inside your routes:

jsxCopyEdit<Route path="/" element={<Layout><Home /></Layout>} />

5. Theme Management Strategies

There are multiple ways to handle themes in React:

  • CSS Variables: Controlled via classes like dark or light.
  • Tailwind CSS: Built-in support for dark mode.
  • Context API: Manage theme state globally.
  • Styled Components: Use props to dynamically change styles.

We’ll focus on Tailwind and Context API.


6. Implementing Light and Dark Themes

Using Tailwind CSS:

  1. Enable dark mode in tailwind.config.js:
jsCopyEditmodule.exports = {
  darkMode: 'class',
  // ...
}
  1. Create a ThemeContext:
jsxCopyEditimport { createContext, useState, useEffect } from 'react';

export const ThemeContext = createContext();

export function ThemeProvider({ children }) {
  const [theme, setTheme] = useState('light');

  useEffect(() => {
    document.documentElement.className = theme;
  }, [theme]);

  const toggleTheme = () =>
    setTheme((prev) => (prev === 'light' ? 'dark' : 'light'));

  return (
    <ThemeContext.Provider value={{ theme, toggleTheme }}>
      {children}
    </ThemeContext.Provider>
  );
}

7. Using Tailwind CSS for Theming

Tailwind gives you utility classes like:

htmlCopyEdit<div className="bg-white dark:bg-gray-800 text-black dark:text-white">
  Hello World
</div>

No need for custom CSS — dark mode is handled automatically based on the class applied to <html> or <body>.


8. Using Context API for Theme Toggle

Use the ThemeContext inside components:

jsxCopyEditimport { useContext } from 'react';
import { ThemeContext } from './ThemeContext';

function ThemeToggleButton() {
  const { theme, toggleTheme } = useContext(ThemeContext);

  return (
    <button onClick={toggleTheme}>
      Switch to {theme === 'light' ? 'Dark' : 'Light'} Mode
    </button>
  );
}

9. Adding Transitions and Enhancing UX

Enhance your theme transitions with Tailwind’s transition utilities:

htmlCopyEdit<div className="transition-colors duration-300 bg-white dark:bg-gray-900">
  Smooth transition between themes
</div>

You can also use icons, animations, and save theme preferences to localStorage.


10. Best Practices for Navigation and Theming

  • Use semantic HTML and accessible navigation (aria labels, roles).
  • Keep navigation links consistent across all pages.
  • Store the user’s theme preference using localStorage.
  • Avoid unnecessary re-renders by memoizing theme contexts.
  • Group your routes by feature or layout type if the app grows large.

11. Conclusion

Building a multi-page app with consistent navigation and theming is foundational for a polished user experience. With the combination of React Router and Tailwind CSS, paired with Context API for state management, you can create elegant, navigable, and theme-aware applications efficiently.