Stop 11 · Next.jsTopics · 9/16

Dynamic Routes

Part of the Frontend Developer Roadmap

In short

You can't make a separate file for every blog post or product. Dynamic routes let one file handle thousands of URLs, each with its own data.

Routes with a variable segment (`[slug]`, `[id]`) that map a single file to many URLs — the basis of blog posts, product pages and user profiles.

The jaadu climbs into one of many identical train coaches holding a ticket.

Think of it like this

Train coach and berth numbers

Every coach has the same layout. Only the number changes: S4, berth 32. The railway doesn't build a new coach design per passenger. One page file is the coach design, and the slug or id in the URL is your berth number.

Watch it happen

One file, many colleges

Browser
[slug]/page
Data

GET /colleges/iim-a

1/6The URL matches app/colleges/[slug], so slug is iim-a.

The big ideas

What you need to know

Square brackets

app/blog/[slug]/page.tsx matches /blog/anything and gives you slug as a param.

params is a Promise

Since Next.js 15, you await params before reading values: const { slug } = await params.

Catch-all routes

[...slug] matches many segments, like /docs/a/b/c, and gives you an array.

notFound()

If no data exists for that slug, call notFound() to show your 404 page.

See it in code

Walk through the code

tsx
1// app/colleges/[slug]/page.tsx2import { notFound } from "next/navigation";3import { getCollege } from "@/lib/colleges";4 5type Props = { params: Promise<{ slug: string }> };6 7export default async function CollegePage({ params }: Props) {8  const { slug } = await params;9  const college = await getCollege(slug);10  if (!college) notFound();11 12  return <h1>{college.name}, {college.city}</h1>;13}

1/4params is a Promise holding the slug from the URL.

/colleges/iim-ahmedabad gives slug = "iim-ahmedabad". Unknown slugs get a proper 404 instead of a crash.

Save yourself the pain

Common mistakes

Oops

Using numeric ids in public URLs like /colleges/482.

Do this instead

Use readable slugs like /colleges/iim-ahmedabad. They're better for users and search results.

Oops

Rendering an empty page when the slug doesn't exist.

Do this instead

Call notFound() so users and Google get a real 404.

Your mission

Profile pages for your friends

~20 min

Quick check

Which folder name matches both /docs/setup and /docs/setup/linux/install?

Go deeper

  1. 1Build a `[slug]/page.tsx` route and read the param with the `params` prop.
  2. 2Learn catch-all routes (`[...slug]`) for arbitrarily nested paths.
  3. 3Combine dynamic routes with `generateStaticParams` to pre-render known pages.

More topics at this stop

Stuck on this topic? Ask an Insider

Get 1:1 guidance from people who've walked this exact path — on the InsideEdge app.

Download
InsideEdge