Dynamic Segments

Name a folder [param] to capture a part of the URL, then read it from the async params prop.

Syntaxapp/blog/[slug]/page.tsx

To build pages for many items (blog posts, products, users) you use a dynamic segment: a folder named with square brackets, like [id]. Whatever value appears in that URL position is passed to your page.

Reading params (Next 15+)

In the App Router, params is a Promise. Make your page async and await it before using the values.

Example

Example · typescript
// app/blog/[slug]/page.tsx  ->  /blog/anything
export default async function Post({
  params,
}: {
  params: Promise<{ slug: string }>;
}) {
  const { slug } = await params;
  return <h1>Post: {slug}</h1>;
}

When to use it

  • A blog reads the [slug] param to fetch and render the correct post from a CMS.
  • A product page at /products/[id] fetches product details from an API using the id from the URL.
  • A user profile page at /users/[username] displays profile data by passing the username segment to a database query.

More examples

Dynamic segment folder

Brackets around a folder name make it a dynamic segment that captures any value at that position.

Example · bash
app/
└── blog/
    └── [slug]/
        └── page.tsx   # → /blog/my-first-post

Reading params in a page

The params prop is a Promise in Next.js 15+, so it must be awaited to read the segment value.

Example · ts
// app/blog/[slug]/page.tsx
type Props = { params: Promise<{ slug: string }> };

export default async function PostPage({ params }: Props) {
  const { slug } = await params;
  return <h1>Post: {slug}</h1>;
}

generateStaticParams for SSG

generateStaticParams pre-renders every post at build time instead of rendering on demand.

Example · ts
// app/blog/[slug]/page.tsx
export async function generateStaticParams() {
  const posts = await fetch('/api/posts').then(r => r.json());
  return posts.map((p: { slug: string }) => ({ slug: p.slug }));
}

export default async function PostPage({ params }: { params: Promise<{ slug: string }> }) {
  const { slug } = await params;
  return <h1>{slug}</h1>;
}

Discussion

  • Be the first to comment on this lesson.