DEV Community

Cover image for How to Make Dynamic Routing with Next.js
Cath Leyson
Cath Leyson

Posted on

How to Make Dynamic Routing with Next.js

Introduction

Dynamic routing is a powerful feature provided by Next.js that allows us to create flexible and scalable applications.

In this article, we will explore how to implement dynamic routing using Next.js.

We'll walk through the process of setting up dynamic routes, fetching data for specific routes, and rendering components dynamically based on route parameters.

Let's dive in!

Folder Structure

To begin, let's take a look at our folder structure within the pages directory:

pages
  └─ character
       ├─ [id].tsx
       └─ index.tsx

Enter fullscreen mode Exit fullscreen mode

In this structure, we have a character folder that contains two files: [id].tsx and index.tsx. The [id].tsx file will be instrumental in setting up our dynamic routing.

Setting Up Dynamic Routing

Within the character folder, the [id].tsx file is responsible for handling the dynamic routing. Here's an example of its contents:

import type { NextPage } from "next";
import * as A from "@features";

const HeroDetailsPage: NextPage = () => {
  return (
    <A.PageContainer>
      <A.HeroInfoList />
    </A.PageContainer>
  );
};

Enter fullscreen mode Exit fullscreen mode

In this code snippet, we define the "HeroDetailsPage" page, which serves as the template for rendering the details of a specific hero character.

Inside the component, we can include other components, such as HeroInfoList, to display the relevant information.

Fetching Data for Dynamic Routes

To fetch the data for the dynamic routing, we utilize the getHero function, which makes a GET request to retrieve the specific hero's details.

Here's an example of the getHero function:

import axios from "axios";
import { base_url, key, hash } from "@config/keys";
import { useQuery } from "react-query";

async function getHero(id: number) {
  const { data } = await axios.get(`${base_url}/characters/${id}`),{
//other params...
} 
  return data;
}
export function useHero(id: number) {
  return useQuery(["hero details", id], () => getHero(id));
}

Enter fullscreen mode Exit fullscreen mode

In this code snippet, we define the getHero function that takes the "id" parameter and makes a GET request to the Marvel API to fetch the details of the character with the corresponding ID.

The fetched data is returned.

We also define a custom hook, useHero, which takes the "id" parameter and utilizes the useQuery hook from React Query to handle the data fetching process.

It passes the id to the getHero function to fetch the data.

Then, we can utilize the useRouter hook provided by Next.js.

Let's take a look at the HeroInfoList component:

import { useRouter } from "next/router";
import { useHero } from "@features/hero/api";
import { HeroInfo } from "./hero-info";
import * as A from "@features";

export function HeroInfoList() {
  const router = useRouter();
  const { id } = router.query;
  const { data, isLoading, isError } = useHero(Number(id));

  // Handle loading and error states

  const { results } = data?.data || {};

  return (
    <>
      {results?.map((hero: any) => (
        <HeroInfo key={hero.id} {...hero} />
      ))}
      // Rest of the code...
    </>
  );
}

Enter fullscreen mode Exit fullscreen mode

Within the HeroInfoList component, we import the useHero hook from "@features/hero/api" to fetch data for a specific hero. We retrieve the "id" parameter from the router query using Next.js useRouter and pass it to the useHero hook.

Rendering Components Dynamically

Based on the fetched data, we can render components dynamically. In the HeroInfoList component, we iterate over the results array and render a HeroInfo component for each hero.

Creating Dynamic Links

To navigate to the dynamic routes, we can use Next.js' built-in link component. Let's take a look at the CharacterCard component:

import Link from 'next/link';

const Routes =[
characterDetails: "/character/[id]",

//more paths...
]

type CharProps = {
  id: number;
  name: string;
  thumbnail: {
    path: string;
    extension: string;
  };
};

export function CharacterCard({ id, name, thumbnail }: CharProps) {
  return (
    <Link
      href={{
        pathname: Routes.characterDetails,
        query: { id: id },
      }}
    >
      // Rest of the code...
    </Link>

Enter fullscreen mode Exit fullscreen mode

The Routes list contains the route paths for our application. We pass the characterDetails route to the pathname property of the link component, along with the "id" parameter as the query object.

With this setup, when the user clicks on a character card, they will be directed to the HeroDetailsPage component with the corresponding "id" parameter.

So the expected behavior looks like this...

  1. A user clicks on the CharacterCard Component
  2. It navigates through characterDetails path with an ID param in the URL.
  3. It then displays the details about the specific character/hero.

Conclusion

Dynamic routing is a powerful feature of Next.js that enables us to create dynamic and interactive web applications.

In this article, we explored the process of setting up dynamic routes, fetching data for specific routes, and rendering components dynamically based on route parameters.

By leveraging the capabilities of Next.js, we can create flexible and scalable applications that provide an optimal user experience.

Hope this helps!

Top comments (0)