本文へ移動
verified onnext@16.3.5react@19
最終検証日 2026-09-26
Next.js道場

Dynamic server usage の読み方と消し方

実際に出るエラー

Error: Dynamic server usage: Route / couldn't be rendered statically because it used `cookies`. See more info here: https://nextjs.org/docs/messages/dynamic-server-error

cookies などを try で囲んだときに、ビルドのログに出る文言です。

いつ出るのか

cookies() のように開いた人ごとに違うものを読むところを、try で囲むと出ます。

import { cookies } from 'next/headers'
 
export default async function Page() {
  let theme = 'light'
  try {
    theme = (await cookies()).get('theme')?.value ?? 'light'
  } catch (e) {
    console.error('caught:', e)   // ここがビルドのログに出す
  }
  return <p>theme={theme}</p>
}

実機で、ビルドは通り、ログに caught: Error: Dynamic server usage: … と出ました。付いていた digest は DYNAMIC_SERVER_USAGE です。

ページは壊れていない

赤い Error に見えますが、実機ではページは動いていました。

  • ビルドの一覧で、このページは ƒ(開かれるたびに描く)だった
  • 開くと、Cookie に theme=dark を送れば dark、送らなければ light を表示した
  • 開いたときのサーバーのログには、何も出なかった

Cookie はビルドのときには読めません。Next.js は cookies() が呼ばれた時点で合図を投げて描くのをやめ、そのページを「開かれるたびに描く」扱いにします。try で囲むと、その合図が自分の catch に届いてしまう。ログに出ていたのはそれです。

消し方

try の外で読む

Cookie を読むところは try の外に出し、try の中は自分の処理だけにします。

export default async function Page() {
  const store = await cookies()          // try の外
  let name = 'guest'
  try {
    name = await loadProfile()           // 外部の API など、自分の処理だけ
  } catch (e) {
    console.error(e)
  }
  return <p>{store.get('theme')?.value} {name}</p>
}

実機で、ログに Dynamic server usage は出なくなり、ページは ƒ のままでした。

囲むなら unstable_rethrow で投げ直す

囲む範囲を変えられないときは、catch の先頭で next/navigation の unstable_rethrow を呼びます。Next.js の合図なら投げ直し、それ以外なら何もしません。

import { unstable_rethrow } from 'next/navigation'
 
try {
  theme = (await cookies()).get('theme')?.value ?? 'light'
} catch (e) {
  unstable_rethrow(e)
  console.error(e)
}

実機で、ログに出なくなりました。公式ドキュメントによると、redirect や notFound の合図も同じように投げ直します。

似た文言:dynamic = 'error'

ページに export const dynamic = 'error' を付けていると、別の文言でビルドが止まります。

Error: Route / with `dynamic = "error"` couldn't be rendered statically because it used `cookies()`.

'error' は「ビルドのときに描けないものを使ったら止める」という指定です。Cookie を使うと決めたなら外します(Next.js のキャッシュ)。

まとめ

  1. Dynamic server usage は、Next.js の合図を自分の catch が拾ったもの。ページは動いている
  2. Cookie などは try の外で読む。囲むなら catch の先頭で unstable_rethrow(e)
  3. dynamic = 'error' の文言は別物。付けた指定を外す

出典

このページの内容は上記の一次情報を基準に書いています。個人ブログや二次情報を根拠にしていません。

理解できたか試す

では、このコードはどうなりますか。

Cookie が壊れていても落ちないように、読むところを try で囲みました。ビルドは通りましたが、ログに Error: Dynamic server usage と出ています。これは何ですか。

この問題を解くこのテーマの問題 3 問