How Next router handles routing differently from React Router Dom
Published: 2024-06-28 16:22:32

**React** and **Next.js** are similar in some ways, and different in others. One of those differences is in how both frameworks handle routing. As someone who has used React for most of my career, I was surprised to find how different Next.js routing is from React Routing. Understanding these differences is crucial for developers working with either framework. I will continue to update this article as I learn more about Next routing. But for now, this article will cover the following: 

- Declarative vs file-based routing
- Dynamic routing

Before we dive in, it's important to note that routing in React is typically done with **React Router Dom**, an external library. Next.js, however, has its inbuilt routing capabilities. 

Also, this article is written for the [HNG internship](https://hng.tech/internship). It is a three-month-long program where new developers can test themselves. They also offer career services such as recruitment and mentorship. More details [here](https://hng.tech/premium)


Okay, let's explore these differences in detail.

## Declarative vs File-Based Routing

The first major difference between routing in React and Next.js is how routing is handled.

### React Routing

In React, we need to:

1. Add **BrowserRouter** to `index.js`
2. Declare the **Routes** component
3. Nest each **Route** component inside **Routes**
4. Add the intended component we want to route to, and the URL to each **Route** component

Here's an example:

```jsx
// index.js
ReactDOM.render(
  <BrowserRouter>
    <App />
  </BrowserRouter>,
  document.getElementById('root')
);

// App.js
const App = () => {
  return (
    <div>
      <Routes>
        <Route path="/" element={<Home />} />
        <Route path="/about" element={<About />} />
        <Route path="/blog" element={<Blog />} />
        <Route path="/blog/:id" element={<BlogPost />} />
      </Routes>
    </div>
  );
};

export default App;
```

In summary, you have to define each route in React explicitly.

### Next.js Routing

Next.js uses a different paradigm. You don't have to define routes explicitly due to Next's file-based routing, which uses the path of the file where your component is located as the URL of that route.

Using the same example as we used for React, our routes in Next.js might look like this:

```
my-next-app/
├── pages/
│   ├── index.js       // Corresponds to "/"
│   ├── about.js       // Corresponds to "/about"
│   ├── blog/
│   │   ├── index.js   // Corresponds to "/blog"
│   │   └── [id].js    // Corresponds to "/blog/[id]"
├── components/
│   ├── Home.js        // Component used in pages/index.js
│   ├── About.js       // Component used in pages/about.js
│   ├── Blog.js        // Component used in pages/blog/index.js
│   ├── BlogPost.js    // Component used in pages/blog/[id].js
└── public/
    └── ...
```

Next.js chose this file-based routing approach to simplify the routing process and make it more intuitive. It eliminates the need for a separate routing configuration, reducing boilerplate code and making the project structure more straightforward. This approach aligns well with Next.js's goal of providing a more opinionated and streamlined development experience.

In Next.js, we write our JSX inside `About.js` and then render it inside its route, `about.js`. This introduces an important design pattern when using Next.js - separating concerns:

```jsx
// pages/about.js
import About from '../components/About';

export default function AboutPage() {
  return <About />;
}

// components/About.js
import React from 'react';

const About = () => {
  return <h1>About Page</h1>;
};

export default About;
```

In summary, Next.js routes are defined based on the component tree and the respective paths.

## Dynamic Routing

The declarative approach of React Router and the file-based approach of Next.js impact how dynamic routes are built and executed in both frameworks.

### Dynamic Routing in React

In React, you can define a dynamic route by adding a colon to the route URL:

```jsx
// App.js
const App = () => {
  return (
    <div>
      <Routes>
        <Route path="/blog" element={<Blog />} />
        <Route path="/blog/:id" element={<BlogPost />} />
      </Routes>
    </div>
  );
};
export default App;
```

Each blog has a unique URL, so the path is `/blog/whatever-the-title-of-the-blog-is`.

Here's how you would use the dynamic parameter in React:

```jsx
import { useParams } from 'react-router-dom';

const BlogPost = () => {
  const { id } = useParams();

  return (
    <div>
      <h1>Blog Post {id}</h1>
      {/* Use the id to fetch and display the blog post */}
    </div>
  );
};

export default BlogPost;
```

### Dynamic Routing in Next.js

Next.js handles dynamic routing differently:

```
├── pages/
│   ├── blog/          // Corresponds to "/blog" 
│   │   └── [id].js    // Corresponds to "/blog/[id]"
```

Next.js indicates that a route should be dynamic by putting a variable inside square brackets. Here's how we might configure this:

```jsx
import { useRouter } from 'next/router';

const BlogPost = () => {
  const router = useRouter(); // Get the router object
  const { id } = router.query; // Destructure to get the 'id' from the URL

  return (
    <div>
      <h1>Blog Post {id}</h1>
      {/* Use the id to fetch and display the blog post */}
    </div>
  );
};

export default BlogPost;
```

Here's what Next.js is doing under the hood:

1. Inside the `[id].js` file, we call the **useRouter()** method. This method reads `[id].js` file and saves it as an object. We save the result inside the `router` variable.
2. Then, we use the `query` function from **useRouter** to extract a specific part of the object that was generated. In this case, we collect the `id`.
3. Next.js will use that `id` collected as the URL for that route.

Let's see how we would link to this route:

```jsx
import Link from 'next/link';

const BlogList = ({ blogs }) => {
  return (
    <div>
      <h1>Blog List</h1>
      <ul>
        {blogs.map((blog) => (
          <li key={blog.id}>
            <Link href={`/blog/${blog.id}`}>
              <a>{blog.title}</a>
            </Link>
          </li>
        ))}
      </ul>
    </div>
  );
};

export default BlogList;
```

We're taking the URL `/blog/[id].js`, and replacing it with `/blog/${blog.id}`. This way, whatever value `blog.id` holds becomes the URL, giving each individual blog its own unique route.

## Conclusion

While both React (with React Router) and Next.js provide powerful routing capabilities, they approach it differently. React Router uses a more declarative style, while Next.js leverages file-based routing. Understanding these differences can help developers choose the right framework for their needs and use routing effectively in their applications.