No history yet

Advanced Routing

Handling Complex URLs

You already know how to create basic pages by adding files to your pages directory. A file named about.js automatically becomes the /about route. But real-world applications are rarely that simple. What about blog posts, user profiles, or product pages? You can't create a separate file for every single one. This is where advanced routing comes in.

Dynamic Route Segments

Dynamic routes let you create a single template file that can serve countless pages. Imagine a blog. You want URLs like /blog/hello-world or /blog/my-first-post. The structure is the same, but the final part of the URL—the slug—changes for each post.

To create a dynamic route, you use square brackets in the filename. For our blog example, you'd create a file at pages/blog/[slug].js. The [slug] part is a placeholder. When a user visits a matching URL, Next.js will render this component and pass the value from the URL as a parameter.

This pattern allows you to fetch data for the specific post using its slug and display the correct content.

import { useRouter } from 'next/router';

const PostPage = () => {
  const router = useRouter();
  const { slug } = router.query;

  return <p>Showing post: {slug}</p>;
};

export default PostPage;

In this code, we use the useRouter hook to access the router object. The router.query property contains the route parameters. So, if a user navigates to /blog/my-cool-post, router.query will be { slug: 'my-cool-post' }.

Catch-All Routes

Sometimes you need to catch more than one segment of a URL. Think of a documentation site with nested categories, like /docs/guides/getting-started/installation. Or an e-commerce store where products are organized by multiple filters: /shop/womens/dresses/summer.

A dynamic segment [slug] only captures one part. To capture all subsequent parts, you can use a catch-all route. You do this by adding three dots inside the brackets: [...slug].js.

This turns the route parameter into an array containing all the matched segments.

For example, a file at pages/shop/[...filters].js would handle the URL /shop/womens/dresses/summer by setting router.query to { filters: ['womens', 'dresses', 'summer'] }.

FilenameExample URLrouter.query
pages/post/[pid].js/post/abc{ "pid": "abc" }
pages/docs/[...slug].js/docs/a/b/c{ "slug": ["a", "b", "c"] }
pages/shop/[[...slug]].js/shop{}
pages/shop/[[...slug]].js/shop/hats{ "slug": ["hats"] }

Nested Routes and Organization

The power of Next.js's file-based routing is how intuitive it is to organize your application. You create nested routes simply by creating nested folders. This approach keeps your project structure clean and reflects the URL structure directly.

You can combine nested folders with dynamic and catch-all routes to build complex, yet maintainable, routing patterns.

For instance, a file at pages/users/[username]/settings.js would correspond to the URL /users/jane/settings.

This structure is self-documenting. A new developer can understand the app's routes just by looking at the pages directory. There's no need to hunt through a central routing configuration file. This co-location of route definition and page component makes your application much easier to reason about and maintain as it grows.

Time to check your understanding of these advanced routing patterns.

Quiz Questions 1/6

How would you create a file in the pages directory to handle dynamic routes for blog posts, like /blog/hello-world and /blog/my-first-post?

Quiz Questions 2/6

Inside a component located at pages/products/[id].js, how do you access the dynamic id parameter from the URL /products/123?

Mastering these routing techniques unlocks the ability to build sophisticated, data-driven applications with clean and predictable URL structures.