generateStaticParamsの使い方:App Routerで動的ページを静的生成する
generateStaticParamsで動的ルートの値を列挙する方法を解説します。Promise形式のparamsと、Pages RouterのgetStaticPathsとの違いを学びます。
generateStaticParamsで動的ルートの値を列挙する方法を解説します。Promise形式のparamsと、Pages RouterのgetStaticPathsとの違いを学びます。
対象環境と役割
App Routerで使う機能
この記事のApp Routerの例はNext.js 15以降の非同期リクエストAPIに合わせた書き方です。Next.js 16ではCache Componentsを有効にしない構成を前提とします。Pages Routerの記事とは配置先・実行場所が異なるため、プロジェクトのルーターとバージョンを先に確認してください。
TypeScriptの例は5.2以降と、利用するNext.jsが対応するNode.jsを前提にします。app/layout.tsx を備えたApp Routerプロジェクトで実行してください。
引数・戻り値・受け渡すデータ
戻り値はパラメーターオブジェクトの配列で、{ paths, fallback } ではありません。app/products/[slug]/page.tsx なら { slug: string }[] を返します。
コード例を動かす
app/products/[slug]/page.tsx を作成する
以下はこのファイルとして配置する例です。既存ファイルへ追記する場合は、同じ名前のexportやURLが重複しないように統合してください。
const products: Record<string, string> = { notebook: 'ノート', pencil: '鉛筆' };
export function generateStaticParams() {
return Object.keys(products).map(slug => ({ slug }));
}
export const dynamicParams = false;
export default async function Product({ params }: { params: Promise<{ slug: string }> }) {
const { slug } = await params;
return <main><h1>{products[slug]}</h1></main>;
}実行結果と処理の順序
/products/notebook と /products/pencil の2ページが生成対象になります。dynamicParams = false により未列挙の値は受け付けません。
この例はNext.js 15以降のparamsを await で解決します。14以前の同期paramsの例をそのまま最新構成へ移植しないでください。
つまずきやすい点と使い分け
CMSの件数制限を考慮する
CMS一覧APIに取得上限がある場合は全件をページ分割で取得してからパラメーターを返します。最初の100件だけを生成して成功扱いにするミスを防ぎます。
記事追加と再ビルド
ここで列挙するURLはビルド対象のスナップショットです。純粋な静的サイトでCMSに商品を追加しても、そのURLがその場で生成されるわけではありません。
静的出力で使えるか
この例はビルド時に値を確定できるため静的出力に組み込めます。CMS更新などで値を変えた場合は再ビルド・再配置が必要です。
確認課題と実務への応用
自分で値を変えて確認する
3つ目の商品を追加して再ビルドし、URLとページ内容が増えることを確認します。未列挙URLは404として扱われるかも調べます。
開発サーバーだけでなく、本番用ビルドと公開先でも確認します。URLを直接開く場合と画面内のリンクから遷移する場合、値がない場合と不正な値の場合を分けて試すと、型だけでは防げない入力の問題が見つかります。
公式資料と関連する記事
Googleの優先するニュース提供元にSEの部屋を追加
Googleで、いつも読みたい情報源を選べます。登録可否はGoogleの画面で確認できます。
候補にSEの部屋が表示されない場合は、まだ追加できません。