[slug] のような動的セグメント、[...slug] のキャッチオール、[[...slug]] のオプショナルキャッチオールで柔軟なURLを定義できる。
// ── app/blog/[slug]/page.tsx の構造 ─────────────────────
// URL: /blog/hello-world → params.slug = 'hello-world'
// params の型を定義
type Props = { params: { slug: string } };
// ── 動的ページの基本 ─────────────────────────────────
export default async function BlogPost({ params }: Props) {
// params.slug が URL の [slug] に対応
const post = await getPost(params.slug);
if (!post) {
// 記事が見つからない場合は 404 ページを表示
notFound();
}
return (
<article>
<h1>{post.title}</h1>
<p>{post.content}</p>
</article>
);
}
// ── generateStaticParams: ビルド時にURLを静的生成 ────
// これがあると全記事ページを事前に HTML として生成する(高速!)
export async function generateStaticParams() {
const posts = await getAllPosts();
return posts.map(post => ({
slug: post.slug, // 生成する URL のパラメータ
}));
}
// → /blog/hello-world, /blog/react-tips などのHTMLが生成される
// ── 入れ子の動的ルート ───────────────────────────────
// app/users/[userId]/posts/[postId]/page.tsx
type NestedProps = {
params: { userId: string; postId: string }
};generateStaticParamsを定義するとビルド時に静的ページが生成される(SSG)。定義しない場合は動的レンダリング(SSR)になる。