How to Handle Dynamic Routing in Next.js
Tags: webdev, nextjs, frontend, beginners
Published: 2024-04-06 16:41:05

Routing is important in every software application. Dynamic routing helps with the scalability and performance of the application.

For a simple [portfolio website](https://stephengade.com), you can have static routes like `/about`, `/contact`, etc. 

But you will deal with many routes or URLs when it comes to web applications like an eCommerce website, social media application, etc. 

Imagine software engineers at Facebook trying to build a dedicated page for each user who signs up. That will be billions of static URLs and one thing is that these dedicated pages have the same UI (though different data).

React and some other frontend libraries have solved the issue of duplicate UI design with reusable components. Also, you no longer need expensive configuration to dynamically or statically set URLs.

You can handle millions of incoming URLs with a (dynamic) URL setup.

This is a quick demo of what we will be handling in this tutorial.

<img width="100%" style="width:100%" src="https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExbm51dHFwaWQwMzQ0b3ZwNnAzMG1zZThvZjdkYmNsaW43ZDZyazg1cCZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/4wHDxAmuK5itLBvGOB/giphy.gif">

You are quite familiar with this system, let's talk about how it works and how to do it.

## How Does Dynamic Routing Work?

**First: Understand the structure of your application**

For instance for blog posts, the structure can be like `/articles/[blog-post]`. This means all the blog posts are placed in a folder called `articles` inside the Page folder (in the Page directory) or the App folder in the App directory. 

e.g 

```javascript

 page
   | -- articles
        | -- [blog-post].tsx
```

Or 

```javascript
 app
   | -- articles
        | -- [blog-post]
             | -- page.tsx
```


**Second: There must be a unique identifier.**

This unique identity could be the `slug`, `username`, or `id` of the product or blog post.

So that when you go to `/user/${username}`, the details of the username will be fetched and not someone else.

Note that often, `id` is automatically generated at the backend for each item created and added to the database. Most developers will use the `id` since it's by default unique.

But `id` is very ugly. Imagine a link like `/product/138jeknfhklejklrkn3773994889`, while this will work, it is not recommended especially for SEO sake…

So the backend developers can work on what we call `slug`, so that your product page will look something like this: `/product/justin-bieber-merch-3eti`.

The `username` approach is common when dealing with social media apps or marketplace software.

For instance Dev.to makes use of the community member username as a dynamic routing identifier. E.g dev.to/stephengade. But for articles, dev.to uses `slug` approach by concatenating the blog post title with a unique ID.

Twitter also does the same thing e.g _**twitter.com/stephen_olgade**_

These usernames are unique for each user.

Whichever one your development team decides to use, whether slug or ID or username, it must be unique for each page to be rendered.

Let’s put all this into action!

## Routing in Nextjs

We don't have a backend for this tutorial but we have a mock data service to use.

I already have a starter project from my [previous article](https://dev.to/stephengade/build-a-functional-search-bar-in-nextjs-mig) on how to build a functional search bar in Nextjs, you can [check the code here](https://github.com/stephengade/Technical-writing-codes/tree/searchbar/user-profile). 

The file structure is pretty straightforward.

If you cloned the repository, install all the dependencies by running `yarn install` and start the project with `yarn dev`.

You don’t need to use my project structure, you can use the idea in this tutorial to set up a new project for yourself or use it in your existing project.

## This is what we want to do

- Render a list of user profile cards on the homepage
- If a card is clicked, it shows the profile details of the user.

That’s all.

We have built the user profile card and rendered it on the homepage. If you click on a card, nothing is happening yet, that leaves us to the second step.

## How to Handle Dynamic Routing in Nextjs

As said earlier, there must be a unique ID or a king of slug to handle the dynamic routing otherwise your application will throw an error.

In this project, I will be using the username because it is unique for each card and that makes more sense in real-life scenarios. For instance `www.twitter.com/{{username}}`

So this is what we want to do, when we click on the card, we will push the username to the URL (to your desired structure). 

Let’s do both methods, the nested structure or root directory structure.

## The root directory method:

In your `app` folder, create a square folder and call it anything (assuming you’re using the App directory).

To create a square folder in the Nextjs App directory, wrap the group name in squared brackets. E.g. `[user]`. The reason we are doing this is that we don’t want Nextjs to see the folder as a path. Remember that any folder in the app directory is considered a navigation path.

In the `[user]` folder, create a `page.tsx` file.

![Root directory](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/d4q6n9tikuzkydt000hf.PNG)

In the `page.tsx` file, put this code:

```jsx
const UserProfileRoute = ({ params }: { params: { user: string } }) => {
  const username = params.user;
  return <h2>This is {username}</h2>;
};


export default UserProfileRoute;
```

**What happens here:**

In the Nextjs page route, we have access to the current URL parameter by simply destructuring the name of our square bracket folder from `params`

So this `const username = params.user` will be the value of the item we push to the URL. Let’s see this in action. 

Remember we have a profile UI built that does nothing when we click on it, let’s fix that.

Since we want to show the user profile page on the root directory as we set up already, update your profile card with this:

```jsx
import Image from 'next/image'
//Import the profile interface from data.js

import { iProfile } from "../services/data";
import Link from 'next/link';

export const ProfileCard = (props: iProfile) => {


    const { name, email, username, role, photo } = props;


    return (
        <Link href={`/${username}`} target="_blank">
        <div className="profile__card rounded-[15px] border border-solid">
            <Image src={photo} alt={username} className="h-[200px]" height={1000} width={400} />


            <div className=" bg-slate-300 p-3">
                <h2 className="">Name: {name}</h2>
                <p>Role: {role}</p>
                <p>Email: {email}</p>
                <p>follow @{username}</p>


            </div>
        </div>
        </Link>
    )
}
```

Note that we only push the `username` to the URL. If everything is done correctly, we can test it now:

<img width="100%" style="width:100%" src="https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExbm51dHFwaWQwMzQ0b3ZwNnAzMG1zZThvZjdkYmNsaW43ZDZyazg1cCZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/4wHDxAmuK5itLBvGOB/giphy.gif">

You can customize this to fetch and render the user data on that page instead of just displaying the username.

**The nested routing method**

It’s just the same thing we have done, but this time, you will put the square bracket folder inside another (parent) folder.

For instance, if you want the user profile to access with a link like `/user/{username}`, you will name the parent folder ‘user’.

![Nested Route method](https://dev-to-uploads.s3.amazonaws.com/uploads/articles/ucfvsgjbr4tpjlwp2zsb.PNG)

And the Profile card UI you wrapped with:

```jsx
<Link href={`/${username}`}> </Link>
```

will be updated to 

```jsx
<Link href={`/user/${username}`}> </Link> ## note the /user/ the name of the folder which is the path
```

<img width="100%" style="width:100%" src="https://media.giphy.com/media/v1.Y2lkPTc5MGI3NjExOHR3cTZlYWo3MDhyMm41d2gxYzJjM29sdW1wcjRjcWc4bmpmNW9wMiZlcD12MV9pbnRlcm5hbF9naWZfYnlfaWQmY3Q9Zw/6qlUSqqyA8paCArzBx/giphy.gif">


Read more: [Routing: Dynamic Routes | Next.js (nextjs.org)](https://nextjs.org/docs/app/building-your-application/routing/dynamic-routes)