Hello! In our last lesson, we took the first step into client-side routing by setting up React Router using the modern createBrowserRouter API. This prepared our application to understand URLs and render components accordingly.
As mentioned previously, there is another very common and widely-used method for defining routes directly within your components using JSX. In this lesson, we will explore this alternative approach. You will learn how to define application routes using the BrowserRouter, Routes, and Route components. Understanding both methods will make you a more versatile React developer, able to work on a wider range of projects.
The JSX-Based Approach to Routing
While the object-based createBrowserRouter is powerful, many developers find the JSX-based approach more intuitive and easier to read, especially for straightforward applications. This method involves three primary components from react-router-dom:
<BrowserRouter>: This component uses the HTML5 History API to keep your UI in sync with the URL. You wrap it around your application or the part of your app that requires routing. It acts as a context provider, making routing information available to all its descendants.<Routes>: This component is a container for all your individual routes. It intelligently scans its children<Route>elements and renders the one that best matches the current URL.<Route>: This is where the magic happens. Each<Route>component defines a mapping between a URL path and the component that should be rendered for that path.
Let's start by understanding why React Router is necessary and how to get it set up.
React Router Version 6 Tutorial – How to Set Up Router and Route ...
The freeCodeCamp article 'React Router Version 6 Tutorial' provides a great overview of the problem React Router solves and how to get started. We'll read a few key sections.
Please read the following sections: 'React as a Single Page Application (SPA)': This will reinforce why we need a router. 'How to Install React Router': This is a quick recap of the installation command. 'How to Set Up React Router': Focus on this part. It shows how to wrap your root <App /> component with <BrowserRouter> in your index.js or main.jsx file. This is the first crucial step for this method.
Step 1: Configuring BrowserRouter in main.jsx
As you read, the first step is to make routing capabilities available to your entire application. In the previous lesson, we used <RouterProvider>. For this JSX-based approach, we will replace that with <BrowserRouter>.
This video gives a quick, clear demonstration of wrapping your application inside the BrowserRouter component.
Learn React Router v6 In 45 Minutes
Let's watch a short clip from Web Dev Simplified that shows exactly how to wrap your application in <BrowserRouter>.
Watch from 00:44 to 01:53. The video demonstrates installing React Router (which you've already done) and then wrapping the <App> component inside <BrowserRouter> in the index.js file. Your file is likely named main.jsx since you are using Vite, but the principle is identical.
After this step, your src/main.jsx file should be modified to look like this. Notice the change from <RouterProvider> to <BrowserRouter> and the removal of the createBrowserRouter logic.
// src/main.jsx
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App.jsx';
import './index.css';
// 1. Import BrowserRouter
import { BrowserRouter } from 'react-router-dom';
ReactDOM.createRoot(document.getElementById('root')).render(
<React.StrictMode>
{/* 2. Wrap your App component with BrowserRouter */}
<BrowserRouter>
<App />
</BrowserRouter>
</React.StrictMode>
);
Step 2: Defining Routes with <Routes> and <Route>
With <BrowserRouter> set up, we can now define our routes inside the <App> component. First, let's create a few simple components that will act as our "pages".
Create a new folder src/pages and add the following files:
src/pages/HomePage.jsx
function HomePage() {
return (
<div>
<h1>Home Page</h1>
<p>Welcome to our application!</p>
</div>
);
}
export default HomePage;
src/pages/AboutPage.jsx
function AboutPage() {
return (
<div>
<h1>About Us</h1>
<p>This is a simple React application to demonstrate routing.</p>
</div>
);
}
export default AboutPage;
Now, let's use these components to define our routes in App.jsx. The video below will walk you through this process.
React Router 6 – Tutorial for Beginners
This video from freeCodeCamp.org demonstrates how to use the <Routes> and <Route> components to define your page routes. It clearly shows how to map a path to a component.
Watch from 05:54 to 15:05. The first part (until 11:09) explains the basic syntax using simple inline JSX. The second part (from 11:09 onwards) shows the best practice of using imported components for your routes, which is what we just created (HomePage, AboutPage).
After watching the video and applying the concepts, your src/App.jsx should look like this:
// src/App.jsx
// 1. Import Routes and Route
import { Routes, Route } from 'react-router-dom';
// 2. Import your page components
import HomePage from './pages/HomePage';
import AboutPage from './pages/AboutPage';
function App() {
return (
<div>
{/* A navigation bar would typically go here. We'll add it in the next lesson! */}
<hr />
{/* 3. Define your routes */}
<Routes>
<Route path="/" element={<HomePage />} />
<Route path="/about" element={<AboutPage />} />
</Routes>
</div>
);
}
export default App;
Now, if you run your application, you should see the HomePage component. If you manually change the URL in your browser to http://localhost:5173/about, the AboutPage component will render without a full page refresh. You've successfully defined multiple routes!
Step 3: Handling Pages That Don't Exist (404)
What happens if a user navigates to a URL that we haven't defined, like /contact? Currently, the app will render a blank space because no route matches. A professional application should show a "Not Found" or "404" page.
React Router makes this easy with a "catch-all" route. This is a special route that uses * as its path. It will match any URL that hasn't been matched by the other routes defined above it.
First, let's create our 404 page.
src/pages/NotFoundPage.jsx
function NotFoundPage() {
return (
<div>
<h1>404 - Page Not Found</h1>
<p>The page you are looking for does not exist.</p>
</div>
);
}
export default NotFoundPage;
Now, let's see how to add this as a catch-all route.
React Router 6 – Tutorial for Beginners
The same freeCodeCamp.org tutorial has an excellent segment on creating a 404 error page using a catch-all route.
Watch from 19:36 to 22:37. This part explains how to use path="*" to create a route that handles all unmatched URLs. Pay attention to its placement at the end of the route list.
Update your src/App.jsx to include the new NotFoundPage and the catch-all route. It's crucial that this route is the last one in the list.
// src/App.jsx
import { Routes, Route } from 'react-router-dom';
import HomePage from './pages/HomePage';
import AboutPage from './pages/AboutPage';
// 1. Import the NotFoundPage
import NotFoundPage from './pages/NotFoundPage';
function App() {
return (
<div>
<hr />
<Routes>
<Route path="/" element={<HomePage />} />
<Route path="/about" element={<AboutPage />} />
{/* 2. Add the catch-all route at the end */}
<Route path="*" element={<NotFoundPage />} />
</Routes>
</div>
);
}
export default App;
Now, if you navigate to any undefined path like /products or /asdf, you will see your custom NotFoundPage.
Conclusion
In this lesson, you've learned the widely-used JSX-based method for defining routes in a React application. While the createBrowserRouter approach from the last lesson is the most modern, you are now equipped to understand and build routing in the vast majority of React projects you will encounter.
Key Takeaways:
- The JSX-based routing approach uses three main components:
<BrowserRouter>,<Routes>, and<Route>. <BrowserRouter>should wrap your application (usually inmain.jsx) to enable routing.<Routes>acts as a container that finds the best matching route.<Route>maps a specificpathto a componentelement.- A catch-all route with
path="*"should be placed at the end of your route list to handle 404 "Not Found" errors gracefully.
Next Up:
Our application now has multiple "pages," but users can't switch between them without manually typing in the URL. In the next lesson, we will solve this by learning how to use the Link and NavLink components to create a proper navigation menu.