Encodera

Thanks for reading!

Donate to the site — we work hard for you.

Contents

Nested routes

A nested route is an address made of several segments, such as /posts/hello-nextjs/comments. Each segment is a folder, and the folders nest inside each other the same way the parts of the address do.

A comments page

Let us make a separate page with the comments of a post. Create a comments folder inside app/posts/[slug]:

// app/posts/[slug]/comments/page.tsx
export default async function CommentsPage({ params }: { params: Promise<{ slug: string }> }) {
  const { slug } = await params;
 
  return <h1>Comments on post {slug}</h1>;
}

Open /posts/hello-nextjs/comments — "Comments on post hello-nextjs" appears. A nested page also receives the parameters of its parent folders in params.

The blog folder tree

app/
├── page.tsx                  /
├── about/
│   └── page.tsx              /about
└── posts/
    ├── layout.tsx
    ├── page.tsx              /posts
    ├── new/
    │   └── page.tsx          /posts/new
    └── [slug]/
        ├── page.tsx          /posts/hello-nextjs
        └── comments/
            └── page.tsx      /posts/hello-nextjs/comments

The app/posts/layout.tsx layout wraps all these pages except / and /about.

A regular folder wins over a dynamic one

The new and [slug] folders sit side by side. The address /posts/new matches both, but Next.js picks the folder with the exact name. Create the form page:

// app/posts/new/page.tsx
export default function NewPostPage() {
  return <h1>New post</h1>;
}

The address /posts/new opens "New post", not a post page with slug equal to new. The order of files does not matter.

Several parameters

If an address has two dynamic segments, the folders must have different names:

// app/users/[userId]/posts/[slug]/page.tsx
type Props = { params: Promise<{ userId: string; slug: string }> };
 
export default async function UserPostPage({ params }: Props) {
  const { userId, slug } = await params;
  return <p>Author {userId}, post {slug}</p>;
}

The address /users/anna/posts/hello-nextjs shows "Author anna, post hello-nextjs".

Linking to a nested page

An ordinary link leads from the post page to its comments:

// app/posts/[slug]/page.tsx (fragment)
<Link href={`/posts/${slug}/comments`}>Comments</Link>

Common mistake

Putting two dynamic folders with different names side by side, such as app/posts/[slug] and app/posts/[id]. Next.js cannot decide which one matches and fails on start with "You cannot use different slug names for the same dynamic path". One level can hold only one dynamic folder.

Thanks for reading!

Donate to the site — we work hard for you.