<img alt="react routing" data- data-src="https://kirelos.com/wp-content/uploads/2023/09/echo/react-routing.jpg/w=800" data- decoding="async" height="420" src="data:image/svg xml,” width=”800″>

For any non-trivial React application, you must break it down into multiple pages. To do so, it becomes necessary to implement react routing.

This can be an intimidating topic at first. However, this tutorial will get you up to speed with all the necessary fundamentals. In this tutorial, we will be building an app that uses routing.

What is React Routing (Client-side Routing)

<img alt="hal-gatewood-tZc3vjPCk-Q-unsplash" data- data-src="https://kirelos.com/wp-content/uploads/2023/09/echo/hal-gatewood-tZc3vjPCk-Q-unsplash.jpg/w=945,h=630" data- decoding="async" height="630" src="data:image/svg xml,” width=”945″>

React routing is a form of client-side routing implemented in React applications. Client-side routing is an alternative to server-side routing. In server-side routing, the browser makes a GET request to the web server whenever you navigate to a different page. This request could take a few seconds before you get a response.

For a web application where you are constantly moving between pages, the wait time creates a bad user experience. Client-side routing is an alternative to this. Instead of providing the browser with HTML, the app uses JavaScript to generate the HTML for different pages.

You only need to provide an index.html file as an entry point for your app to work. This entry point then loads your JavaScript code. The JavaScript bundle will render pages by manipulating the DOM, handling routing, and implementing app functionality.

Because the server only renders the index.html page, the application is called a single-page application.

Advantages of Client-side Routing

  • It creates a better user experience as the navigation is faster, and the application will be more responsive. With server-side routing, every navigation is a network request with a few seconds of latency.
  • It enables the creation of offline applications as all the code required to run the app can be cached locally. This allows you to build more available applications and offer offline functionality.
  • The application will also use less data as network requests significantly reduce if everything is sent once and some files are cached locally.
  • It also reduces server load as the server only has to render the application once. This contrasts with server-side rendering, where the server continually renders the application.

Next, let’s discuss how to implement react routing.

How to Implement React Routing

For this tutorial, we will be building a simple note-taking application. It will be made up of multiple pages. We will implement client-side routing using React Router DOM to enable the client to navigate between the different pages. We will not be building everything for the app to work. Instead, we will focus on routing.

Prerequisites

<img alt="YouTube video" data-pin-nopin="true" data-src="https://kirelos.com/wp-content/uploads/2023/09/echo/maxresdefault.jpg65129b90a170d.jpg" height="720" nopin="nopin" src="data:image/svg xml,” width=”1280″>

To follow this tutorial, you must understand HTML, JavaScript, and React. You will also need to have Node.js and NPM installed. You can download and install them simultaneously by installing Nodejs from the website. Or follow the guide in the YouTube video embedded.

What We Are Building

The app will have multiple pages. Using react routing, you will be able to navigate to different pages. The designs for the pages are shown below.

The Home page is rendered at the ‘/’ route.

<img alt="home page" data- data-src="https://kirelos.com/wp-content/uploads/2023/09/echo/image-84.png/w=800" data- decoding="async" src="data:image/svg xml,” width=”800″>

The About page is rendered at the ‘/about’ route.

<img alt="About page" data- data-src="https://kirelos.com/wp-content/uploads/2023/09/echo/image-85.png/w=800" data- decoding="async" src="data:image/svg xml,” width=”800″>

Notes Page at the ‘/notes’ route.

<img alt="page route" data- data-src="https://kirelos.com/wp-content/uploads/2023/09/echo/image-86.png/w=800" data- decoding="async" src="data:image/svg xml,” width=”800″>

New Note Page at the ‘/notes/new’ route.

<img alt="New notes" data- data-src="https://kirelos.com/wp-content/uploads/2023/09/echo/image-87.png/w=800" data- decoding="async" src="data:image/svg xml,” width=”800″>

You can see each note in full on the Note Page. This page is rendered at the ‘/routes/’ route, where the is an integer representing the id of the note we want to read.

<img alt="Note 1" data- data-src="https://kirelos.com/wp-content/uploads/2023/09/echo/image-88.png/w=800" data- decoding="async" src="data:image/svg xml,” width=”800″>

Getting Started

To get started, create a new React project. I am going to be using Vite, so the command to initialize a new project is this:

npm create vite@latest scribbble --template react

I specified ‘scribbble’ as the project name and React as the template. Next, I am going to open VS Code using the commands below:

cd scribbble
code .

After VS Code is open, I will return to the terminal window and install react-router-dom. This package makes it easier to implement react routing in your applications.

npm install react-router-dom

We are going to create a file where our notes are going to be stored. Create a src/notes.js file and add the following code:

const notes = [
  {
    id: 1,
    title: "Note 1",
    body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
  },
  {
    id: 2,
    title: "Note 2",
    body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
  },
  {
    id: 3,
    title: "Note 3",
    body: "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.",
  },
];

export default notes;

Next, delete the src/App.css file. We won’t be using it in this project. Also, make sure to remove the import for the App.css file from the App.jsx file.

After that, replace everything in the index.css file with this:

:root{font-family:Inter,system-ui,Avenir,Helvetica,Arial,sans-serif;font-weight:400;color:#404040}*{margin:0;padding:0}.nav-container{display:flex;justify-content:space-between;padding:15px 30px}.home-buttons,.nav{display:flex;gap:10px}a{text-decoration:none;color:inherit;font-weight:600}h1{font-size:63px;margin:20px 0}input,textarea{border:1px solid #f1f1f1;background-color:#fafafa;outline:0;padding:10px;width:100%}textarea{resize:none;font-family:inherit}.container{padding:15px}.primary{background-color:#8a2be2;color:#fff}.secondary{background-color:#eee}.button{padding:15px 30px;font-size:16px;border:none;font-weight:700;border-radius:7px;cursor:pointer}.home-container{height:300px;display:flex;flex-direction:column;align-items:center;justify-content:center}.new-note-container{padding:20px}.new-note-form{display:flex;flex-direction:column;align-items:center;width:500px;gap:20px;margin:auto;border-radius:7px;padding:20px 30px}.notes-list{display:grid;grid-template-columns:1fr 1fr 1fr;gap:30px;padding:0 60px}.note{border:1px solid #d3d3d3;padding:15px;border-radius:7px}.note h2{font-size:1rem;margin-bottom:10px}.note p{color:#585858;font-size:.9rem;cursor:pointer}.note-container{display:flex;align-items:center;justify-content:center;padding:50px}.note-content{width:500px}

Next, create the following files for the pages we are going to be creating:

  • src/pages/Home.jsx
  • src/pages/About.jsx
  • src/pages/Note.jsx
  • src/pages/NewNote.jsx
  • src/pages/Notes.jsx

Then, create the file for the Navigation Bar component. This file will be located at src/components/NavBar.jsx

Setting Up React Routing

With our app set up, we will set up routing in our application next.

Open the App.jsx file and delete everything inside. Next, add the following imports to the top of the file:

import { BrowserRouter, Routes, Route } from "react-router-dom";
import { NavBar } from "./components/NavBar";
import { Home } from "./pages/Home";
import { About } from "./pages/About";
import { Notes } from "./pages/Notes";
import { Note } from "./pages/Note";
import { NewNote } from "./pages/NewNote";

We are importing the BrowserRouter, Routes, and Routes components from react-router-dom. These will be used to set up a router. Next, we imported the NavBar from our components directory and several pages from our pages files. We haven’t implemented the pages yet, but we will soon.

Next, we are going to set up our App component:

export default App () {

}

Then, we add the following markup within our return statement:

return (
    
      
    
)

This renders the BrowserRouter, a React component provided by the react-router-dom component. This component configures a router that works within the browser. Our app will be contained inside those tags.

Next, we will add the navigation bar and create a Routes component.

return (
    
      
      
);

Inside the BrowserRouter element, we added a NavBar. We will define this element later, but it creates the links at the top of each page. Instead of writing it separately for each page, we will create one NavBar.

Then, we created a container element. This element is not necessary for routing. We just added it to apply styling.

Inside the container, we added the Routes component. This is where different pages will be rendered depending on the route the browser is on. Everything inside the Routes component will be re-rendered every time the route changes.

Lastly, we add the routes for the different pages.

  return (
    
      
      
);

The Home component will be rendered when the path is ‘/’, and the About component will be rendered on the ‘/about’ route. The Notes component will be rendered at the ‘/notes’ route. We also have the ‘/notes/new’ route and ‘/notes/:id’ defined as nested routes.

Nested Routes Explained

A route can contain inner routes. These are called nested routes. The path to these nested routes will be joined to the parent route to form the complete path. For example, the ‘notes’ and ‘new’ routes will be combined to ‘/notes/new’.

As for how the components are rendered when the user navigates to the parent route, only the parent component will be rendered. However, the parent and nested components will be rendered together when they navigate the nested route.

To render both components together, the Notes component must render an Outlet component that specifies where the Note component will be embedded. You will see this later when we start creating the Pages.

Dynamic Routes

So far, we have been specifying the literal route we want to match. For example, the ‘/’ and ‘about’ routes. However, react-router-dom enables us to specify dynamic routes. A dynamic route contains a portion that can be matched against a query parameter. When matched, the query parameter is passed on to the page.

For example, inside the ‘posts’ parent route, we have a nested route that contains a dynamic portion specified by :id. This route accepts any text in place of :id , and that text becomes available to the Note component as id.

Building the Navigation Bar

We use Link components instead of normal anchor tags to navigate using react-router-dom. Therefore, our navigation bar should look like this:

import { Link } from "react-router-dom";

export function NavBar() {
  return (
    
Scribbble
); }

Add the code to src/pages/NavBar.jsx.

Building Out the Pages

Next, we are going to build the pages. For the Home Page, add the following code to the src/pages/Home.jsx.

<img alt="home page" data- data-src="https://kirelos.com/wp-content/uploads/2023/09/echo/image-84.png/w=800" data- decoding="async" src="data:image/svg xml,” width=”800″>
import { useNavigate } from "react-router-dom";

export function Home() {
  const navigate = useNavigate();

  return (
    

Notes for professionals

); }

In the HomePage, we would like to use buttons to navigate. As a result, we use the useNavigate hook to navigate programmatically. We imported the hook and then called it inside the Home Component. The return value after calling the hook is a function you can use to navigate.

<img alt="About page" data- data-src="https://kirelos.com/wp-content/uploads/2023/09/echo/image-85.png/w=800" data- decoding="async" src="data:image/svg xml,” width=”800″>

Next, we will define the About page. Add the following code to your src/pages/About.jsx file.

export function About() {
  return (
    

About

Simple Notes is the best note-taking application for professionals

); }

After this, we will define the Notes page.

<img alt="page route" data- data-src="https://kirelos.com/wp-content/uploads/2023/09/echo/image-86.png/w=800" data- decoding="async" src="data:image/svg xml,” width=”800″>

In this component, we also have to include an Outlet component that will be used to render any nested routes. For this reason, our src/pages/Notes.jsx page will look like this.

import { Outlet, useNavigate } from "react-router-dom";
import notes from "../notes";

export function Notes() {
  const navigate = useNavigate();
  return (
    
{notes.map((note) => { return (
{ navigate("https://geekflare.com/notes/" note.id); }} >

{note.title}

{note.body.slice(0, 100)}

); })}
); }

Next, we define the Note page.

<img alt="New notes" data- data-src="https://kirelos.com/wp-content/uploads/2023/09/echo/image-87.png/w=800" data- decoding="async" src="data:image/svg xml,” width=”800″>

This will be rendered for an individual note. To decide on a note to render, Notes will access the id specified in the dynamic portion of the route. To do so, we use the userParams hook. Therefore, this should be code inside your src/pages/Note.jsx file:

import { useParams } from "react-router-dom";
import notes from "../notes";

export function Note() {
  const params = useParams();
  const note = notes.find((note) => note.id == params.id);
  return (
    

{note.title}

{note.body}

); }
<img alt="New notes" data- data-src="https://kirelos.com/wp-content/uploads/2023/09/echo/image-87.png/w=800" data- decoding="async" src="data:image/svg xml,” width=”800″>

Lastly, we will create the NewNote component inside the src/pages/NewNote.jsx using the following code:

export function NewNote() {
  return (
    

New Note