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
- Why Multi-Page Apps in React?
- Setting Up Page Routes with React Router
- Creating a Navigation Bar
- Structuring Pages and Layouts
- Theme Management Strategies
- Implementing Light and Dark Themes
- Using Tailwind CSS for Theming
- Using Context API for Theme Toggle
- Adding Transitions and Enhancing UX
- Best Practices for Navigation and Theming
- 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
orlight
. - 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:
- Enable dark mode in
tailwind.config.js
:
jsCopyEditmodule.exports = {
darkMode: 'class',
// ...
}
- 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.