Next.js 13で導入されたgenerateStaticParams()
関数は、getStaticPaths()
関数の代替である。動的ルートセグメントとセットで使う。
関数の概要
generateStaticParams()
関数は、動的ルートセグメントのlayout.tsx
、あるいはpage.tsx
の中で定義する(tsx
がスタンダードだが、js
でもjsx
でもts
でもよい)。
これはApp Routerで採用された仕組みである。Pages Routerでは機能しない。
例えば、トップページの下に任意のセグメントをぶら下げたい場合、app/[seg]/page.tsx
に以下のように定義する(seg
は任意の文字列)。
generateStaticParams()
関数の返り値には、{ セグメント名: 値 }
の配列を指定する。キーに指定するセグメント名は、フォルダ名に指定した動的ルートセグメント名([xxx]
みたいなやつ)と対応していなければならない。
また、各ページのパスは、{ params: { seg: "そのページのセグメント値" } }
という形でページのコンポーネントに渡される。
ちなみにNext.jsの公式ドキュメントには以下のようなサンプルコードが記述されている。
これがgenerateStaticParams()
関数の基本的な使い方である。
引数
generateStaticParams()
関数には、オプションでparams
という引数が渡される。
この引数は、上位のセグメントのlayout.tsx
、あるいはpage.tsx
にgenerateStaticParams()
関数が定義されている場合に、{ params: { 親セグメント名:"親セグメント値" } }
を返す。階層が深い場合は、ご先祖セグメント名とその値のキーバリューがすべて渡される。
自身が最上位の場合、{ params: {} }
が返る。
返り値について
1階層だけを対象とする場合(=各階層でgenerateStaticParams()
関数を定義する場合)は、先のように{ セグメント名: "値" }
を指定すればいい。
ただ、ネストを1つのgenerateStaticParams()
関数で賄うこともできる。この場合、返り値は以下のように指定する。
サンプルルート | 返り値のパターン |
---|---|
app/[slug1]/[slug2] |
{ slug1: string, slug2: string }[] |
app/[...slug] |
{ slug: string[] }[] |
app/[slug1]/[slug2]
のパターンでは、最下層のセグメント(この場合は[slug2]
)にあるlayout.tsx
あるいはpage.tsx
にgenerateStaticParams()
関数を定義する。
各階層には、対応するpage.tsx
を用意しておく必要がある。
app/[...slug]
のパターンでは、そのまま対象のセグメント(この場合は[...slug]
)の直下のlayout.tsx
あるいはpage.tsx
にgenerateStaticParams()
関数を定義する。
注意したいのは、子セグメントを指定したからといって親セグメントまで指定したことにはならない点である。例えば返り値に[{ slug:["seg1","seg2"] }]
を渡した場合、/seg1/seg2
はサポートされるが、/seg1
はサポートされない。[{ slug:["seg1"] }, { slug:["seg1","seg2"] }]
としてやる必要がある。
なお、こちらのパターンでは、動的ルートセグメント直下のpage.tsx
が、以降のセグメントにも割り当てられる。
ハマったエラー0
該当の階層のlayout.tsx
(あるいはpage.tsx
)のfunction Layout()
(あるいはfunction Page()
)が正しくエクスポートされていない。
定義とエクスポートに問題がなければ解消する。きっと。
ハマったエラー1
このエラーは、[xxx]
というフォルダ下にあるpage.tsx
のgenerateStaticParams()
の返り値に{ xxx: "yyy" }
が含まれていないと発生する。
プロパティのキー(xxx
)がセグメント名([xxx]
)と対応しているか。あるいは、アクセスしたいページのセグメントが"yyy"
と対応しているかを確認するとよい。対応させれば解消する。たぶん。
ハマったエラー2
動的ルートをネストしているのに、子セグメントのgenerateStaticParams()
が受け取る引数が空({ params:{} }
)になる。
原因不明だが、これは親ルートのpage.tsx
でgenerateStaticParams()
関数を定義すると発生する。そのまま関数をlayout.tsx
に移すと解消する。おそらく。