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

Cookies can only be modified の直し方

実際に出るエラー

Error: Cookies can only be modified in a Server Action or Route Handler.
Read more: https://nextjs.org/docs/app/api-reference/functions/cookies#options

ページや部品を描く途中で Cookie を書いたり消したりしたときに出るエラーです。

いつ出るのか

ページや部品を描いている途中で Cookie を変えようとすると出ます。実機で確かめました。

import { cookies } from 'next/headers'
 
export default async function Page() {
  const c = await cookies()
  c.set('session', 'abc')      // ここで止まる
  return <p>ログインしました</p>
}

消すときも同じです。ログアウトのつもりで c.delete('session') をページに書いても、同じ文言になりました。

なぜ書けないのか

ページを描くのは表示のための処理です。開いただけで状態が変わってはいけません。同じページを2回開いたら2回ログインした、では困ります。

だから書き込みは、送信を受け取る側に限られています。

Cookie を読める場所と、書ける場所
場所読む書く・消す
ページ・レイアウト(Server Component)できるできない
Server Function(フォームの送信先)できるできる
Route Handler(route.ts)できるできる

直し方

書き込みを、フォームの送信先へ移します。

書くのは送信先。ページは読むだけ
ページで書く
export default async function Page() {
  const c = await cookies()
  c.set('session', key)
  return <p>ログインしました</p>
}

開いた瞬間に 500。

送信先で書く
'use server'
 
export async function signIn(formData: FormData) {
  const c = await cookies()
  c.set('session', key, { httpOnly: true })
  redirect('/mypage')
}

書いてから、別のページへ移す。

実際にこの形で動いているものが最小構成のログインにあります。説明用に書き直したものではなく、そのページを動かしている本物のファイルです。ログアウトも同じく送信先で delete しています。

直したあとに確かめること

  • 本番ビルドで一度開く。このエラーは開くまで出ません
  • 送信先で、呼んだのが誰かを確かめているか。Server Function は画面を通らずに直接呼ばれ得ます(認証をどこで確かめるか)
  • そのページに force-static を付けていないか。付いていると、ログインしていない状態の画面が全員に配られます(キャッシュの考え方)

出典

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

理解できたか試す

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

ログインしたら Cookie に鍵を入れたいので、ページの中で set しました。ビルドは通りました。このページを開くとどうなりますか。

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