Dynamic Routing in Next.js: Simplifying Complex Navigation

gl

Gulshan kumar

@glushan

Clap121

Next.js is a powerful framework for building modern web applications, and its dynamic routing system is a standout feature. With the introduction of the app directory in Next.js 13, managing complex navigation has become even more streamlined and efficient. Whether you're building a blog, an e-commerce platform, or any data-driven app, dynamic routing is essential for creating scalable, user-friendly websites.

In this blog, we’ll dive into the following aspects:

  • What is dynamic routing in Next.js?

  • How dynamic routes work in the app directory.

  • Real-world examples of dynamic routing.

  • Nested and catch-all routes.

  • Dynamic routing with data fetching.


1. What is Dynamic Routing in Next.js?

Dynamic routing allows you to define routes that adapt to dynamic segments of your URL, making it possible to serve content based on variables like user IDs, product IDs, or slugs.

For example:

  • Static route: /about

  • Dynamic route: /product/[id]

  • In dynamic routes, [id] is a placeholder that can be replaced with actual values like /product/123 or /product/456.


2. How Dynamic Routes Work in the app Directory

The app directory, introduced in Next.js 13, brings a new file-based routing system using folders. Here’s how dynamic routing works in this setup:

Defining Dynamic Segments

Dynamic segments are created by wrapping the folder name in square brackets. For example:

Plain Text

app/
     product/
          [id]   //Dynamic route
           page.js

If you want to create a dynamic route for products, the folder structure would look like this:

Plain Text

app/
  product/
      [id]/
        page.js

Code for page.js

Here’s a basic example:

javascript

export default function ProductPage({ params }) {
  const { id } = params; // Access the dynamic segment
  return (
      <div>
          <h1>Product ID: {id}</h1>
          <p>This is the detail page for product {id}.</p>
      </div>
  );
}

URL

  • /product/123 → Displays "Product ID: 123"

  • /product/456 → Displays "Product ID: 456"

3. Real-World Examples of Dynamic Routing

1. Blog Posts

Dynamic routes make it easy to serve blog posts by slug:

Plain Text

app/
  blog/
    [slug]/
      page.js

javascript

export default function BlogPost({ params }) {
    const { slug } = params;
    return <h1>Reading Blog Post: {slug}</h1>;
}

2. User Profiles

Render user profiles based on their unique username:

Plain Text

app/
  user/
    [username]/
  
        page.js

javascript

export default function UserProfile({ params }) {
      const { username } = params;
      return <h1>Welcome to {username}'s profile!</h1>;
}

4. Nested and Catch-All Routes

Nested Dynamic Routes

You can nest dynamic routes by creating additional folders:

Plain Text

app/
  product/
    [id]/
      review/
        [reviewId]/
          page.js

In this case:

  • /product/123/review/456 renders the component in page.js.

Catch-All Routes

Catch-all routes allow you to handle multiple segments with a single route using [[...slug]].

Folder structure:

Plain Text

app/
  blog/
    [[...slug]]/
      page.js

Code example:

javascript

export default function BlogCatchAll({ params }) {
  const { slug } = params; // 'slug' is an array of segments
    return (
      <div>
          <h1>Dynamic Blog Path</h1>
          <p>Path: {slug?.join('/') || 'Home'}</p>
       </div>
  );
}

URLs handled:

  • /blog → Displays "Path: Home"

  • /blog/tech → Displays "Path: tech"

  • /blog/tech/react → Displays "Path: tech/react"


5. Dynamic Routing with Data Fetching

Dynamic routes often require data fetching to display relevant information. In the app directory, you can fetch data using async functions or libraries like fetch.

Example with fetch

Suppose you fetch product details from an API based on the dynamic segment:

javascript

export default async function ProductPage({ params }) {
  const { id } = params;

  // Fetch product data
  const res = await fetch(`https://api.example.com/products/${id}`);
  const product = await res.json();

  if (!product) {
    return <p>Product not found</p>;
  }

  return (
    <div>
        <h1>{product.name}</h1>
        <p>{product.description}</p>
        <p>Price: ${product.price}</p>
      </div>
  );
}

Best Practices for Dynamic Routing

  1. Use meaningful dynamic segments: Instead of generic names like [id], use descriptive terms like [slug] or [username].

  2. Handle errors gracefully: Provide a fallback for invalid or missing parameters.

  3. Pre-render when possible: Use generateStaticParams to pre-render pages for known data.

  4. Secure sensitive data: Avoid exposing sensitive information in dynamic routes.


Conclusion

Dynamic routing in Next.js, especially with the app directory, simplifies the process of building scalable and maintainable navigation systems. Whether it’s a simple blog or a multi-level e-commerce site, the flexibility of dynamic segments ensures your application is ready to handle diverse user interactions.

With features like nested routes, catch-all routes, and built-in support for data fetching, Next.js makes building complex navigation systems intuitive. Start exploring dynamic routing today and unlock the full potential of your Next.js applications!