Building a Multi-Page App with Navigation and Theming

Table of Contents

  1. Introduction
  2. Setting Up the Project
  3. Creating Multiple Pages in React
  4. Implementing Navigation with React Router
  5. Adding Theming with Context API
  6. Managing State Across Pages
  7. Building the Layout Components
  8. Enhancing User Experience with Smooth Navigation
  9. Handling Routing and Nested Routes
  10. Conclusion

1. Introduction

Building a multi-page application (MPA) in React requires careful planning of routing, navigation, and theming. In this module, we will explore the steps involved in building a scalable MPA, including how to set up routing, create a consistent theme across all pages, and manage state between different parts of the app. By the end of this module, you will have a fully functional multi-page React app that is easy to navigate and looks great.


2. Setting Up the Project

To begin, let’s set up a new React project. We’ll use Vite for fast development and build times.

  1. Create a new React project using Vite: bashCopyEditnpm create vite@latest my-multi-page-app --template react cd my-multi-page-app npm install
  2. Install React Router for Navigation: bashCopyEditnpm install react-router-dom

React Router will allow us to set up dynamic routing between different pages in our app.


3. Creating Multiple Pages in React

In an MPA, each “page” is essentially a component. To create multiple pages, we’ll create separate components for each of them:

  1. Create a folder structure: cssCopyEditsrc/ components/ Header.js Footer.js pages/ Home.js About.js Contact.js App.js
  2. Home Page Component (src/pages/Home.js): jsxCopyEditconst Home = () => { return ( <div> <h1>Welcome to the Home Page</h1> </div> ); }; export default Home;
  3. About Page Component (src/pages/About.js): jsxCopyEditconst About = () => { return ( <div> <h1>About Us</h1> </div> ); }; export default About;
  4. Contact Page Component (src/pages/Contact.js): jsxCopyEditconst Contact = () => { return ( <div> <h1>Contact Us</h1> </div> ); }; export default Contact;

4. Implementing Navigation with React Router

With the pages set up, we need to implement navigation between them. We’ll use React Router to handle the routing.

  1. Configure the Router in App.js: jsxCopyEditimport { BrowserRouter as Router, Route, Routes } from 'react-router-dom'; import Home from './pages/Home'; import About from './pages/About'; import Contact from './pages/Contact'; import Header from './components/Header'; import Footer from './components/Footer'; function App() { return ( <Router> <Header /> <Routes> <Route path="/" element={<Home />} /> <Route path="/about" element={<About />} /> <Route path="/contact" element={<Contact />} /> </Routes> <Footer /> </Router> ); } export default App;
  2. Create a Navigation Bar in Header.js: jsxCopyEditimport { Link } from 'react-router-dom'; const Header = () => { return ( <nav> <ul> <li> <Link to="/">Home</Link> </li> <li> <Link to="/about">About</Link> </li> <li> <Link to="/contact">Contact</Link> </li> </ul> </nav> ); }; export default Header;

This basic setup allows us to navigate between the home, about, and contact pages.


5. Adding Theming with Context API

In many applications, it’s important to maintain consistent styling across different pages. We’ll use the Context API to manage a theme that can be toggled across pages.

  1. Create a ThemeContext (src/context/ThemeContext.js): jsxCopyEditimport React, { createContext, useState, useContext } from 'react'; const ThemeContext = createContext(); export const useTheme = () => useContext(ThemeContext); export const ThemeProvider = ({ children }) => { const [theme, setTheme] = useState('light'); const toggleTheme = () => { setTheme((prevTheme) => (prevTheme === 'light' ? 'dark' : 'light')); }; return ( <ThemeContext.Provider value={{ theme, toggleTheme }}> {children} </ThemeContext.Provider> ); };
  2. Wrap the App with ThemeProvider in App.js: jsxCopyEditimport { ThemeProvider } from './context/ThemeContext'; function App() { return ( <ThemeProvider> <Header /> <Routes> <Route path="/" element={<Home />} /> <Route path="/about" element={<About />} /> <Route path="/contact" element={<Contact />} /> </Routes> <Footer /> </ThemeProvider> ); } export default App;
  3. Toggle the theme in Header.js: jsxCopyEditimport { useTheme } from '../context/ThemeContext'; const Header = () => { const { theme, toggleTheme } = useTheme(); return ( <nav className={theme}> <ul> <li> <Link to="/">Home</Link> </li> <li> <Link to="/about">About</Link> </li> <li> <Link to="/contact">Contact</Link> </li> <li> <button onClick={toggleTheme}>Toggle Theme</button> </li> </ul> </nav> ); };

6. Managing State Across Pages

If you need to share state between multiple pages, you can use the React Context API or Redux to manage global state. For example, if you want to share the user’s login state across different pages, you can wrap your app in a UserContext provider.


7. Building the Layout Components

For a multi-page app, it’s important to have reusable layout components, such as a header, footer, sidebar, etc. This allows you to maintain consistency and modularity in your design.

jsxCopyEdit// Layout.js
import Header from './Header';
import Footer from './Footer';

const Layout = ({ children }) => {
  return (
    <div>
      <Header />
      <main>{children}</main>
      <Footer />
    </div>
  );
};

export default Layout;

Then, wrap each page component inside the Layout component to keep the layout consistent across all pages.


8. Enhancing User Experience with Smooth Navigation

To improve the user experience, consider adding smooth scrolling or animations when switching between pages. You can use libraries like Framer Motion to add page transitions and animations.


9. Handling Routing and Nested Routes

React Router supports nested routes, which can be useful if you need more complex page structures. For instance, if you want to have an About page with multiple sub-pages, you can set up nested routes like this:

jsxCopyEdit<Route path="/about" element={<About />}>
  <Route path="team" element={<Team />} />
  <Route path="company" element={<Company />} />
</Route>

This allows users to navigate to about/team or about/company while keeping the About page layout intact.


10. Conclusion

By following this module, you now know how to create a scalable, multi-page React app. You’ve learned how to set up routing, manage global state with the Context API, and apply consistent theming throughout your application. In future modules, we will delve deeper into more advanced React topics and explore ways to optimize and scale your app.