Demo, all content is generated
Question

Claude says cookies().set works in my page but Next.js throws an error

Solved · 691 views · asked by dirk_vl · edited

I want to remember the selected language. Claude wrote in app/page.tsx:

const cookieStore = await cookies()
cookieStore.set('lang', 'nl')

Error:

Error: Cookies can only be modified in a Server Action or Route Handler.

Claude keeps insisting it's correct and moves the code around inside the page.

What I’ve tried

Asked it to fix the error 3 times, it tried try/catch, then 'use server' at the top of the page file.

Comment

2 answers

Marked as helpful by the asker
rafa_dev · edited

The error is right, Claude is wrong. A Server Component page renders after the response headers have started, so it can read cookies but not set them. Setting has to happen where a response is being built:

// app/actions.ts
'use server'
import { cookies } from 'next/headers'

export async function setLanguage(lang: string) {
  (await cookies()).set('lang', lang, { path: '/', maxAge: 60 * 60 * 24 * 365 })
}

Call it from a form or button in a client component. Reading in the page with (await cookies()).get('lang') is fine.

'use server' at the top of a page file is not a thing, remove that.

Comment
Works. I think I need to stop trusting 'it's correct' when the error message literally says the answer. dirk_vl · edited
Nice clear answer. The 'response already started' explanation is the key. jonas_k · edited
jonas_k · edited

Useful habit: when Claude and an error disagree, paste the error and say "search the Next.js docs for this exact message". The framework error is almost always the more reliable of the two.

Comment
Good habit, will do. dirk_vl · edited