Quiz
Warm-up from 'Async server components': how does a server component wait for data?
One file, a thousand pages
A blog has one post layout but thousands of post URLs. You cannot create a folder per post. Instead you create one dynamic segment by wrapping a folder name in square brackets:
app/blog/[slug]/page.js
This single file serves /blog/hello-world, /blog/why-frameworks-win, and every other /blog/<anything> URL. The changing part is handed to your component as the params prop. This should feel familiar: in Backend with Node.js you wrote app.get("/posts/:id") and read req.params.id. Same idea, spelled with brackets instead of a colon.
Reading params (await it!)
// app/blog/[slug]/page.js export default async function PostPage({ params }) { const { slug } = await params; const res = await fetch(`https://api.example.com/posts/${slug}`); const post = await res.json(); return <h1>{post.title}</h1>; }
Decode it:
- In current Next.js,
paramsis a Promise, so you mustawaitit before destructuring. Older tutorials show plainparams.slug, which is the outdated API. - Visiting
/blog/hello-worldgivesslug === "hello-world", which the component uses to fetch exactly that post. - One file, one fetch, infinitely many URLs.
Quiz
With app/shop/[productId]/page.js deployed, a user visits /shop/42. What does await params resolve to?
Code exercise · javascript
Blog posts need URL-safe slugs like the ones in [slug] routes. Write slugify(title): lowercase the title, remove every character that is not a lowercase letter, digit, or space, trim the ends, and turn each run of spaces into a single hyphen. Regex from Advanced JavaScript does the heavy lifting.