Dynamic Routes and Parameter Passing in Next.js
Tags: nextjs, javascript, webdev, react
Published: 2024-05-24 11:40:01

Next.js, the popular JavaScript framework for server-side React applications, continues to evolve and improve. One of its most powerful features is the routing system, which in version 14 of Next.js has been enhanced even further, making dynamic routes and parameter passing easier and more flexible. In this article, we will explore how these dynamic routes work and how we can pass parameters in Next.js.

## What are Dynamic Routes?

Dynamic routes are routes that depend on certain parameters. For example, you might have a blog route that looks like this: `/blog/:id`, where `:id` is a parameter that changes depending on the post you want to display. This allows for cleaner and more semantic URLs, such as `/blog/1234` for the post with ID 1234.

## Creating Dynamic Routes

Creating a dynamic route in Next.js is very straightforward. You simply need to create a file in your pages directory with square brackets `[]` around the parameter name. For example, to create the aforementioned blog route, you would create a file called `[id].js` in your blog pages directory.

```jsx
// pages/blog/[id].js

import { useRouter } from 'next/router'

export default function BlogPost() {
  const router = useRouter()
  const { id } = router.query

  // Fetch the blog post data using the ID

  return (
    <div>
      <h1>Post {id}</h1>
      {/* Render the post content here */}
    </div>
  )
}
```

In this file, we import `useRouter` from `next/router`, which allows us to access the route parameters. Then, we extract `id` from `router.query`.

### Capturing Nested Parameters

Next.js also allows capturing nested parameters and multiple dynamic parameters in a route. Here’s an example:

```jsx
// pages/blog/[category]/[id].js

import { useRouter } from 'next/router'

export default function BlogPost() {
  const router = useRouter()
  const { category, id } = router.query

  // Fetch the blog post data using the category and ID

  return (
    <div>
      <h1>{category} Post {id}</h1>
      {/* Render the post content here */}
    </div>
  )
}
```

In this case, you can capture both `category` and `id` from the URL, allowing for routes like `/blog/tech/1234`.

## Passing Parameters to Dynamic Routes

Passing parameters to a dynamic route is as simple as providing the parameters as part of the URL. For example, if you wanted to navigate to the blog post with id `1234`, you could do it like this:

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

export default function BlogList({ posts }) {
  return (
    <div>
      {posts.map((post) => (
        <Link href={`/blog/${post.id}`} key={post.id}>
          <a>{post.title}</a>
        </Link>
      ))}
    </div>
  )
}
```

In this example, we are iterating over a list of blog posts and creating a link to each post using its `id`. Clicking on the link navigates to the `/blog/1234` route, passing `1234` as the `id` parameter to the dynamic route.

## Pre-rendering and Data Fetching with `getStaticProps` and `getServerSideProps`

Next.js offers two main methods for fetching data: `getStaticProps` for static generation and `getServerSideProps` for server-side rendering. These methods are very useful when working with dynamic routes.

### Using `getStaticProps` with Dynamic Routes

`getStaticProps` allows you to pre-render a page at build time, which is ideal for content that doesn’t change frequently. Here’s an example:

```jsx
// pages/blog/[id].js

import { useRouter } from 'next/router'

export default function BlogPost({ post }) {
  const router = useRouter()
  const { id } = router.query

  if (router.isFallback) {
    return <div>Loading...</div>
  }

  return (
    <div>
      <h1>{post.title}</h1>
      <p>{post.content}</p>
    </div>
  )
}

export async function getStaticPaths() {
  const paths = await fetchAllPostIds() // Fetch all post IDs

  return {
    paths: paths.map((id) => ({ params: { id } })),
    fallback: true, // or 'blocking' to generate on request
  }
}

export async function getStaticProps({ params }) {
  const post = await fetchPostData(params.id) // Fetch post data by ID

  return {
    props: {
      post,
    },
  }
}
```

In this example, `getStaticPaths` is used to define which routes should be pre-rendered. `getStaticProps` fetches the necessary data for a specific route based on its `id`.

### Performance Optimisation

Next.js automatically optimises dynamic routes using techniques like static page generation at build time and deferred loading, improving both performance and user experience. For example, with `fallback: true`, Next.js can generate pages dynamically when navigating to a new route for the first time.

## Conclusion

Dynamic routes and parameter passing are powerful features of Next.js that allow you to create parameter-based routes in a simple and flexible way. With Next.js version 14, working with dynamic routes and parameters is easier than ever. Whether you’re creating a blog, or any other application that requires parameter-based routes, Next.js’s dynamic routes are an indispensable tool.

By leveraging Next.js’s capabilities for pre-rendering and dynamic generation, you can ensure that your applications are fast and efficient, providing an excellent user experience.