generateStaticParams で cookies が使えない
実際に出るエラー
generateStaticParams の中で cookies や headers を読んだときに出るビルドエラーです。
何が起きているか
generateStaticParams は、ビルドのときに「どのページを作るか」を決める関数です。
import { cookies } from 'next/headers'
export async function generateStaticParams() {
const store = await cookies() // ← ここで止まる
return [{ lang: store.get('lang')?.value ?? 'ja' }]
}
ビルドのときには、ページを開いた人がいません。だから Cookie もヘッダーもありません。文言もそのとおりのことを言っています(ビルドのときには HTTP のリクエストが無い)。
実機では、cookies() でも headers() でも同じ形の文言で止まりました。止まるのは、ビルドが作るページを集める段階です。
- BuildgenerateStaticParams を呼ぶ
作るページの一覧を受け取る。開いた人はまだいない。
- Build一覧のぶんだけページを描く
ここで描いたものが、全員に同じく配られる。
- Browser開いた人が来る
Cookie を持って来るのはここから。
直し方
「作るページを決める」ことと「開いた人に合わせる」ことを、分けます。
作るページの一覧は、データから返す
一覧は、リクエストに関係なく決まるものから作ります。
export function generateStaticParams() {
return [{ lang: 'ja' }, { lang: 'en' }] // 対応する言語をすべて
}
データベースやファイルから読んでも構いません。開いた人によって変わらないものであれば、ビルドのときに読めます。
開いた人に合わせるのは、ページの中で
どの言語を見せるかを Cookie で決めたいなら、ページの中で cookies() を読みます。
ただし、cookies() を読んだページは開かれるたびに描かれるようになります(キャッシュの解説)。事前に作っておく意味がなくなるので、generateStaticParams と一緒に使う理由も薄くなります。
output export のときは特に
output: 'export' で静的なファイルだけを書き出すときは、generateStaticParams が必須です(generateStaticParams が無いエラー)。書き出したあとはリクエストを受けるサーバーがいないので、サーバー側で Cookie を読める場所はありません。
出典
- nextjs.org/docs/messages/next-dynamic-api-wrong-context
- nextjs.org/docs/app/api-reference/functions/generate-static-params
このページの内容は上記の一次情報を基準に書いています。個人ブログや二次情報を根拠にしていません。