The Talent500 Blog
reactjs

Client-side routing in ReactJS using the react-router-dom library

Routing is an essential technique for navigating among pages on a website based on user requests and actions. When we want to build a React application with multiple pages, we need to implement a routing feature into the app. By default, React does not provide routing. To achieve this, we use the react-router-dom library. In this blog, you will learn a new way to create routing in a React application.

Before writing this blog, I was searching for information about it on Google. Can you believe there are no blogs that explain new ways to create a router in a React app, except for its official documentation? In the official documentation, they did not explain the details in my opinion. So, it is the best place to learn about creating routing in a React app with the latest routers recommended by their official docs.

Have a look before going deep into the blog, and explore the different routes of this web app.

React Router DOM

A separate library named React Router DOM enables routing in React applications and allows the defining of multiple routes in a React application.

Why React Router DOM

React is a famous JavaScript framework ideal for building single-page applications. As you know React does not include many advanced features like routing by default.

Therefore, React Router is an excellent choice of navigation for these single-page applications to render multiple views or pages.

React Router is a popular standard library for routing among various view components in React applications. It helps keep the user interface in sync with the URL.

The three main packages related to React Router are:

  1. react-router: Contains the core functionality of React Router, including route-matching algorithms and hooks.
  2. react-router-dom: Includes everything in react-router and adds a few DOM-specific APIs.
  3. react-router-native: Includes everything in react-router and adds a few React Native-specific APIs.

What Is React Router DOM

The primary functionality of react-router-dom is implementing dynamic routing in web applications.

Based on the platform and the requirements of the application, react-router-dom supports component-based routing, which is the ideal solution for routing if the React application is running on the browser.

Client-Side Routing VS Server-Side Routing

When JavaScript is used on a web page, it is executed in web browsers. In this case, JavaScript works as a Client-side language.

However, Server-side JavaScript executes on the server that allows us to access databases, file systems, etc.

So in this blog, our main goal is to create client-side routing using ReactJS, so let’s deep dive into it.

Set-Up To React Project And react-router-dom

First things first, we need to create a React project and set up the react-router-dom library as well. We can create a React project using various tools, but I would like to create it using Vite.

Here are the following commands to create a React project using Vite:

Client-side routing in ReactJS using the react-router-dom library 1npm create vite@latest

cd folderName // change the directory

npm install   // Download the dependencies

npm run dev   // Run the local server

Now we need to download the react-router-dom library into our existing project before running the local server. We download this library using this npm i react-router-dom command.

Alright, to demonstrate it in front of you, I need to create a navigation bar for the React app. To create it, we can leverage the power of Bootstrap.

I hope you know how to connect Bootstrap to a React application. For now, we can use CDN links to include Bootstrap in our project.

Now the next step will be to download the react-router-dom library into our project. So follow this command to download it.

npm i reactrouterdom

Create App Router Using createBrowserRouter

createBrowserRouter is the recommended router for all web projects. It uses specific functions and components from the react-router-dom library. Before using it, we need to import it into our project.

import Root from “./components/Root”;

import { createBrowserRouter} from “react-router-dom”;

Then we can configure the routing, meaning what will happen on a specific route URL. So a routing configuration is defined using the createBrowserRouter function, which is provided by the react-router-dom library.

How to configure a route

After importing createBrowserRouter, we need to create a routing configuration, such as:

  • What will happen when the path ends with (/)?
  • What will happen when the path ends with (/blog)?
  • What will happen when the path ends with (/about)?
  • What will happen when the path ends with (/contact)?

The answer to these questions should be provided inside the routing configuration.

const appRouter = createBrowserRouter([

  {

    path: “/”,

    element: <Root />,

  },

]);

The createBrowserRouter is a function that receives an array of objects. This object contains some properties; in this case, it defines that when the root path (/) is accessed, then the <Root/> component should be rendered as the element.

RouterProvider

The RouterProvider is a component that is provided by the react-router-dom library, so again, we need to import it into our existing project.

import {RouterProvider } from “react-router-dom”;

function App() {

  return <RouterProvider router={appRouter} />;

}

export default App;

As we know, App() is a React component that returns some piece of JSX code that defines the structure of the application.

Inside the App() component, a RouterProvider component is rendering with a router prop set to appRouter. This is where React Router’s routing configuration is provided to the application.

Congratulations, We have built our first route. Navigate into the browser and type (/), and now you will see your <Root/> component is rendering.

Replace the anchor element with a Link Component

A Link component is an element that lets the user navigate to another page by clicking or tapping on it but without reloading the entire page. That’s why we need to replace all <a> (anchor) elements with <Link/> components.

This <Link/> component is provided by the react-router-dom library, so again, we need to import it into our existing project.

import { Link } from “react-router-dom”;

After importing it, we are ready to replace all anchor elements with <Link> components.

<Link to=“/”> My Logo</Link>

<Link to=“/blog”>Blog</Link>                 

<Link to=“/about”>About Us</Link>

<Link to=“/contact”> Contact Us</Link>

Did you notice that other than the <Link> component, we have also replaced the href attribute with the to prop?

Worry not, The to prop of each <Link> component defines the destination route that the link should navigate to when clicked. For example:

  • <Link to=”/” > navigates to the root route (“/”) or Home page.
  • <Link to=”Blog” > navigates to a route named “Blog” or Blog page.
  • <Link to=”/about” > navigates to a route named “about” or About Us page.
  • <Link to=”/contact” > navigates to a route named “contact” or Contact Us page.

All right, We have created multiple Link elements, but we have not yet created a routing configuration according to all link elements.

import “./App.css”;

import Root from “./components/Root”;

import Blog from “./components/pages/Blog”;

import About from “./components/pages/About”;

import Contact from “./components/pages/Contact”;

import { createBrowserRouter, RouterProvider } from “react-router-dom”;

const appRouter = createBrowserRouter([

  {

    path: “/”,

    element: <Root />,

  },

  {

    path: “/blog”,

    element: <Blog />,

  },

  {

    path: “/about”,

    element: <About />,

  },

  {

    path: “/contact”,

    element: <Contact />,

  },

]);

const App = () => {

  return <RouterProvider router={appRouter} />;

};

export default App;

As you can see, I have created multiple routes according to the Link element. Where:

  • path: The path property defines the URL path for the route. Such as:
  • “/” – represents the root URL path for the home page.
  • “/blog” – represents a path for a blog page.
  • “/about” – represents a path for an about page.
  • “/contact” – represents a path for a contact page.
  • element: The element property defines the React component that should be rendered when the corresponding URL path is accessed. Like:
  • <Root /> is a React component that will be rendered when the root path (“/”) is accessed.
  • <Blog /> is a React component that will be rendered when the “/blog” path is accessed.
  • <About /> is a React component that will be rendered when the “/about” path is accessed.
  • <Contact /> is a React component that will be rendered when the “/contact” path is accessed.

Awesome! Now we have successfully created routes for the different link elements of the page. Have a look; at the end, you will get the GitHub repository for the code.

Note: The value of the path and the value of the to props should be the same.

Creating a Nested Route Using An Outlet Component

Did you notice that when we click on a particular link element, the corresponding element is rendered? But the navigation bar disappeared?

Worry not; we can easily fix this issue by utilizing the concept of the nested route. We need to modify the existing routing configuration a little bit. Here is how:

const appRouter = createBrowserRouter([

  {

    path: “/”,

    element: <Root />,

    children: [

      {

        path: “/blog”,

        element: <Blog />,

      },

      {

        path: “/about”,

        element: <About />,

      },

      {

        path: “/contact”,

        element: <Contact />,

      },

    ],

  },

]);

As you can see in the above code snippets, there is a “children” property that accepts a list of objects.

  • path: It defines the URL path for the route. such as, (/, /blog, /about, /contact). They are defined as routes in the configuration.
  • element: It is used to define the React component that should be rendered when the corresponding route is matched.
  • children: This property is an array of child routes associated with a parent route. In this case, all of the defined routes (blog, about, and contact) are nested under a parent route with the path (/).

It means that when the URL matches (/), the <Root /> component will be rendered, and within it, the child routes (blog, about, contact) can be rendered as needed.

Also, we must update the JSX of the <Root/> component. Here is how:

import Navbar from “./Navbar”;

import { Outlet } from “react-router-dom”;

const Root = () => {

  return (

    <>

      <Navbar />

      <Outlet />

    </>

  );

};

export default Root;

The <Outlet /> component is imported from the react-router-dom library. The <Outlet /> component is a placeholder provided by react-router-dom for rendering the matched child routes based on the current URL path.

In other words, when the URL matches a route defined in our application’s routing configuration, the component associated with that route will be rendered within the <Outlet /> placeholder.

Basically, the <Outlet /> component acts as a location where the content of the child route will be injected. It allows the router to dynamically render the appropriate component based on the URL path.

Congratulations! We have created a nested route where the navigation bar is intact at the same position, whereas the content of the different paths is changing dynamically.

Client-side routing in ReactJS using the react-router-dom library 2

Handling Errors When Path Does Not Match

Everything is perfect now, but what will happen when we type the wrong path in the browser’s address bar?

Client-side routing in ReactJS using the react-router-dom library 3

Oh my god, an error has occurred. So now we need to handle this error by leveraging the power of the react-router-dom library.

So what I am going to do is create an error page, which will be displayed when the path is mismatched.

Client-side routing in ReactJS using the react-router-dom library 1

After creating the <Error/> component, we can design our error beautifully, but for now, I’m keeping it simple.

import style from “./Error.module.css”;

const Error = () => {

  return (

    <div className={style[“error-container”]}>❌ Something Went Wrong ❌</div>

  );

};

export default Error;

And update the router configuration with the errorElement property:

const appRouter = createBrowserRouter([

  {

    path: “/”,

    element: <Root />,

    errorElement: <Error />,

    children: […],

  },

]);

The errorElement property is used to specify a component that should be rendered if an error occurs during the routing process. This could be an error like a route not being found or any other routing-related error. This means that if an error occurs while navigating to this route, the <Error /> component will be rendered.

Now the error looks something like this: 🙂

Client-side routing in ReactJS using the react-router-dom library 5

However, if we want to show a custom error, then we can also do this because the react-router-dom library also provides a custom hook known as “useRouteError”.

Here is the code: When the error occurs, the useRouteError hook returns an object with an error response.

Client-side routing in ReactJS using the react-router-dom library 6

import style from “./Error.module.css”;

import { useRouteError } from “react-router-dom”;

const Error = () => {

  const err = useRouteError();

  console.log(err); // Error Response

  return (

    <div className={style[“error-container”]}>

      <h1>❌ Something Went Wrong ❌</h1>

      <h2>{err.data}</h2>

      <h3>{err.status + ” “ + err.statusText} 🥲</h3>

    </div>

  );

};

export default Error;

The purpose of useRouteError is to access and handle routing-related errors in our React application.

We can use this hook to handle 404 errors or any other routing error that might occur. This hook returns an error object that provides information about the error, which we can then use to customize error handling in our application.

Well, we are done! We have created dynamic routing in our React application and also handled the error. Have a look.

Client-side routing in ReactJS using the react-router-dom library 7

Here is the complete code for this project; you can get it from this GitHub repository. And if you have any doubts, then directly reach out to me via Twitter.

Conclusion

We’ve dug into the world of routing in React applications and discovered just how crucial it is for creating seamless user experiences. React may not provide routing out of the box, but thanks to the power of libraries like react-router-dom, we can easily implement routing into our projects.

What makes this blog unique is that it seeks to fill a gap in the vast sea of online resources. When I embarked on my journey to find a comprehensive guide on creating routers in React, I was surprised to find very few blogs that explored new ways to tackle this topic. The official documentation, while reliable, sometimes lacks the detailed explanations that learners like us crave.

Also, if you are looking for a JavaScript or React job, please search for them on Talent500.co

4+
Ajay Yadav

Ajay Yadav

I am a frontend developer and am eager to deep dive into the technologies through my content.

Add comment