Next.jsRoutingWeb DevelopmentTutorial

Next.js Routing: Exploring Dynamic Routes and Route Groups

Master Next.js routing with dynamic routes, route groups, and advanced routing patterns. Learn how to create flexible, scalable navigation in your Next.js applications.

By Vibe Code Basics10 min read
Next.js Routing: Exploring Dynamic Routes and Route Groups

Next.js Routing: Exploring Dynamic Routes and Route Groups

Routing is one of the most powerful features of Next.js. In this guide, we'll explore dynamic routes, route groups, and other advanced routing patterns that will help you build more flexible and scalable applications.

If you're new to Next.js, check out our Getting Started with Next.js guide first.

Understanding File-Based Routing

Next.js uses a file-based routing system. Every file in the app directory automatically becomes a route. This means:

  • app/page.js/
  • app/about/page.js/about
  • app/blog/page.js/blog

Dynamic Routes

Dynamic routes allow you to create pages that accept parameters. Use square brackets [] in your folder or file name to create dynamic segments.

Single Dynamic Segment

Create a folder named [id] to capture a single dynamic parameter:

app/
  blog/
    [slug]/
      page.js

This creates a route like /blog/my-post where my-post is the slug.

Example:

// app/blog/[slug]/page.js
export default async function BlogPost({ params }) {
  const { slug } = await params;
  
  return (
    <div>
      <h1>Blog Post: {slug}</h1>
    </div>
  );
}

Multiple Dynamic Segments

You can have multiple dynamic segments in a single route:

app/
  shop/
    [category]/
      [product]/
        page.js

This matches routes like /shop/electronics/laptop.

// app/shop/[category]/[product]/page.js
export default async function Product({ params }) {
  const { category, product } = await params;
  
  return (
    <div>
      <h1>{category} - {product}</h1>
    </div>
  );
}

Catch-All Routes

Use [...slug] to catch all segments:

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

This matches /docs, /docs/getting-started, /docs/getting-started/installation, etc.

// app/docs/[...slug]/page.js
export default async function Docs({ params }) {
  const { slug } = await params;
  const path = slug ? slug.join('/') : 'index';
  
  return (
    <div>
      <h1>Documentation: {path}</h1>
    </div>
  );
}

Optional Catch-All Routes

Use [[...slug]] for optional catch-all routes that also match the parent:

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

This matches both /blog and /blog/any/nested/path.

Route Groups

Route groups allow you to organize routes without affecting the URL structure. Use parentheses () in folder names.

app/
  (marketing)/
    about/
      page.js
    contact/
      page.js
  (shop)/
    products/
      page.js
    cart/
      page.js

The parentheses are ignored in the URL, so these routes are:

  • /about
  • /contact
  • /products
  • /cart

Use Cases for Route Groups

  1. Organize by feature: Group related pages together
  2. Different layouts: Apply different layouts to different groups
  3. Code splitting: Organize for better code organization

Parallel Routes

Parallel routes allow you to render multiple pages simultaneously using slots. This is useful for dashboards or complex layouts.

app/
  dashboard/
    @analytics/
      page.js
    @team/
      page.js
    layout.js

Route Handlers

Route handlers let you create API endpoints alongside your pages:

// app/api/users/route.js
export async function GET(request) {
  return Response.json({ users: [] });
}

export async function POST(request) {
  const body = await request.json();
  // Handle POST request
  return Response.json({ success: true });
}

For more on API routes, check out our guide on Adding API Routes in Next.js.

Navigation

Next.js provides the Link component for client-side navigation:

import Link from 'next/link';

export default function Navigation() {
  return (
    <nav>
      <Link href="/">Home</Link>
      <Link href="/about">About</Link>
      <Link href="/blog">Blog</Link>
    </nav>
  );
}

Programmatic Navigation

Use the useRouter hook for programmatic navigation:

'use client';

import { useRouter } from 'next/navigation';

export default function MyComponent() {
  const router = useRouter();
  
  const handleClick = () => {
    router.push('/dashboard');
  };
  
  return <button onClick={handleClick}>Go to Dashboard</button>;
}

Best Practices

  1. Use descriptive folder names: Make your route structure clear
  2. Keep routes shallow: Avoid deeply nested routes when possible
  3. Use route groups for organization: Group related routes together
  4. Leverage dynamic routes: Use them for flexible, scalable routing
  5. Optimize with loading states: Use loading.js for better UX

Conclusion

Next.js routing is powerful and flexible. By mastering dynamic routes, route groups, and other routing patterns, you can build applications that are both scalable and maintainable.

Next Steps:

Happy routing! 🚀

Related Articles