IT-Q

動的ルートで params.slug を直接読んだら、値が入っていませんでした。なぜですか。

params が Promise になっているからです。15 で Promise になり、16 で同期的な読み方が使えなくなりました。15 で動いていたコードが 16 で壊れるので、上げた直後に踏みます。

面接官が見ているのは🔴 Next.js 15 の破壊的変更。古いサンプルを写すと必ず踏む。

よくある答えと、面談でどう見られるか

  • params が Promise になったため。await してから読む
    15 で Promise になり、16 で同期的な読み方が使えなくなりました。古い記事や生成AIの出力には旧形式が多く残っています。
  • フォルダ名の角括弧の書き方を間違えている
    その場合はルート自体が一致せず 404 になります。値が空なら Promise を疑います。
  • generateStaticParams を書いていないから
    書かなくても動的に生成されます。値が入らない理由にはなりません。
  • Server Component では params を受け取れないから
    受け取れます。page の props として渡ります。

模範解答

params が Promise になっているからです。型としても params: Promise<{ slug: string }> と書き、const { slug } = await params のように await します。

変更は2段階です。14 までは同期的なオブジェクトでした。15 で Promise になりましたが、互換のため同期的に読んでも動いていました。16 でその互換が無くなり、params.slug を直接読むと値が取れなくなりました。つまり「15 では動いていたコードが 16 で壊れる」ので、上げた直後に踏みやすい箇所です。ネット上のサンプルや生成AIの出力には、直接読む古い形が今も多く残っています。

同じ方向の変更として searchParams、cookies()、headers() も非同期になりました。個別に暗記するより「リクエスト依存の情報は、必要になるまで待たない形に揃えられた」と理解しておく方が、次の変更にもついていけます。

対象: Next.js 16(App Router) 照合した一次資料: 公式ドキュメント 照合: 2026-10-25 最終更新: 2026-10-25
お使いの版で挙動が違う場合があります。誤りに気づいたらこの解説を報告するから教えてください。