React Router is a powerful library that allows you to handle routing in your React application with ease. One of the most important features of React Router is the ability to nest routes within other routes. This allows you to create complex applications with multiple pages and sub-pages, all with their own unique URLs. In this tutorial, we will be exploring how to implement nested routes with React Router.
What Are Nested Routes?
Nested routes are a way of organizing your application into a hierarchical structure. This structure is made up of parent and child routes, where child routes are nested within parent routes. This allows you to create a multi-level navigation system, where each page can have its own sub-pages.
Setting Up a Basic React Router Application
Before we dive into nested routes, let's start by setting up a basic React Router application. We will create a simple "Hello, World!" application and add routing to it.
To get started, let's create a new React project using create-react-app. Open up your terminal and run the following command:
npx create-react-app my-app
cd my-app
Next, let's install React Router. Run the following command in your terminal:
npm install react-router-dom
Once the installation is complete, open up the src/index.js file in your project and add the following code:
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter, Route, Switch } from 'react-router-dom';
const App = () => {
return (
<div>
<h1>Hello, World!</h1>
</div>
);
};
ReactDOM.render(
<BrowserRouter>
<Switch>
<Route exact path="/" component={App} />
</Switch>
</BrowserRouter>,
document.getElementById('root')
);
Here, we have imported the necessary components from react-router-dom and created a simple App component that renders a h1 tag with the text "Hello, World!". We have also wrapped our Switch component in a BrowserRouter component and added a Route component with the path / that renders our App component.
If you run your application now with npm start, you should see the "Hello, World!" text on the page.
Implementing Nested Routes
Now that we have our basic application set up, let's move on to implementing nested routes. To do this, we will add a new page to our application and nest it within our existing route.
Creating a New Page Component
First, let's create a new component for our new page. Create a new file in your src directory called About.js and add the following code:
import React from 'react';
const About = () => {
return (
<div>
<h2>About</h2>
<p>This is the about page</p>
</div>
);
};
export default About;
This component simply renders a h2 tag with the text "About" and a p tag with the text "This is the about page".
Adding a Nested Route
Now that we have our new component, let's add a new route to our application that renders this component. Open up the src/index.js file and update the code as follows:
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter, Route, Switch, Link } from 'react-router-dom';
import About from './About';
const App = () => {
return (
<div>
<h1>Hello, World!</h1>
<nav>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
</ul>
</nav>
<Switch>
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
</Switch>
</div>
);
};
const Home = () => {
return (
<div>
<h2>Home</h2>
<p>This is the home page</p>
</div>
);
};
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById('root')
);
Here, we have imported our About component and added a new Route component with the path /about that renders our About component. We have also added a new Link component in our nav section that links to the /about path.
If you run your application now with npm start and navigate to http://localhost:3000/about, you should see the text "About" and "This is the about page" on the page.
Adding Nested Routes
Now that we have a nested route, let's add another level of nesting. We will create a new page component called Contact and nest it within our About component.
First, create a new file in your src directory called Contact.js and add the following code:
import React from 'react';
const Contact = () => {
return (
<div>
<h3>Contact</h3>
<p>This is the contact page</p>
</div>
);
};
export default Contact;
This component simply renders a h3 tag with the text "Contact" and a p tag with the text "This is the contact page".
Next, open up the src/About.js file and update the code as follows:
import React from 'react';
import { Route, Link } from 'react-router-dom';
import Contact from './Contact';
const About = ({ match }) => {
return (
<div>
<h2>About</h2>
<nav>
<ul>
<li>
<Link to={`${match.url}/contact`}>Contact</Link>
</li>
</ul>
</nav>
<Route path={`${match.path}/contact`} component={Contact} />
<p>This is the about page</p>
</div>
);
};
export default About;
Here, we have imported our Contact component and added a new Route component with the path **${match.path}/contact**
that renders our Contact component. We have also added a new Link component in our nav section that links to the /about/contact path.
Notice that we have used the match prop to construct the URL for our nested route. This allows us to use relative URLs instead of absolute URLs, which makes our code more flexible and easier to maintain.
If you run your application now with npm start and navigate to http://localhost:3000/about/contact`, you should see the text "About", "Contact", and "This is the contact page" on the page.
Adding Dynamic Nested Routes
Now, let's add some dynamic behavior to our nested routes. We will create a new page component called Profile that takes a username parameter from the URL and renders a user profile page.
First, create a new file in your src directory called Profile.js and add the following code:
import React from 'react';
const Profile = ({ match }) => {
return (
<div>
<h3>{match.params.username}</h3>
<p>This is the user profile page for {match.params.username}</p>
</div>
);
};
export default Profile;
This component takes the username parameter from the URL using the match.params object and renders a h3 tag with the username and a p tag with some text.
Next, open up the src/App.js file and update the code as follows:
import React from 'react';
import ReactDOM from 'react-dom';
import { BrowserRouter, Route, Switch, Link } from 'react-router-dom';
import About from './About';
import Profile from './Profile';
const App = () => {
return (
<div>
<h1>Hello, World!</h1>
<nav>
<ul>
<li>
<Link to="/">Home</Link>
</li>
<li>
<Link to="/about">About</Link>
</li>
</ul>
</nav>
<Switch>
<Route exact path="/" component={Home} />
<Route path="/about" component={About} />
<Route path="/user/:username" component={Profile} />
</Switch>
</div>
);
};
const Home = () => {
return (
<div>
<h2>Home</h2>
<p>This is the home page</p>
</div>
);
};
ReactDOM.render(
<BrowserRouter>
<App />
</BrowserRouter>,
document.getElementById('root')
);
Here, we have added a new Route component with the path /user/:username that renders our Profile component. This route uses a dynamic parameter called username that can be any string value.
If you run your application now with npm start and navigate to http://localhost:3000/user/john, you should see the text "john" and "This is the user profile page for john" on the page.
Conclusion
In this article, we have learned how to implement nested routes with React Router. We started by creating a new component and adding a new route to our application. Then, we added another level of nesting by creating a new page component and nesting it within our existing About component. Finally, we added some dynamic behavior to our nested routes by creating a new page component that takes a parameter from the URL. By following these steps, you can create complex and dynamic applications with React Router.