Cookies, headers, and request data
Request data connects the browser to server rendering, but reading it changes when and where a route can be rendered. Use it close to the decision that needs it.
Request APIs are asynchronous and request-specific
In current Next.js, cookies and headers are asynchronous APIs. Their values only exist when a request arrives, so reading them opts the relevant route into dynamic work.
Do not read a cookie in the root layout simply because one deeply nested button needs it. That moves request-specific work higher in the tree and can remove useful prerendering opportunities.
import { cookies } from 'next/headers'
export async function DensityPreference() {
const store = await cookies()
const density = store.get('density')?.value ?? 'comfortable'
return <span>Density: {density}</span>
}Server Components read cookies, mutations write them
A Server Component can read cookies sent with the incoming request. It cannot set a cookie while rendering because response headers may already be streaming. Write or delete cookies in a Server Action or Route Handler.
Session cookies should normally use httpOnly, secure in production, an appropriate sameSite policy, an expiry, and a narrow path where possible. These flags reduce risk, but they do not replace session validation on the server.
Headers are useful context, not trusted identity
Headers can carry content negotiation, trace identifiers, forwarded host information, and platform metadata. Values supplied by the public internet are untrusted unless a trusted proxy overwrites and verifies them.
Never grant access because a caller sent x-user-role: admin. Authentication should establish identity through a verified session or token, then authorisation should load permissions from a trusted source.
Set broad response policy in configuration
Stable headers such as Strict-Transport-Security, X-Content-Type-Options, Referrer-Policy, and a carefully tested Content-Security-Policy are often clearer in next.config than repeated across handlers.
Route Handlers remain the right place for response-specific values such as a generated file name, webhook acknowledgement, or endpoint-specific cache policy.
Debug the complete request chain
When a cookie works locally but not in production, inspect domain, path, secure, sameSite, expiry, and the exact Set-Cookie response. When a host or protocol looks wrong, inspect the platform proxy headers and your trusted-host configuration.
Log names and decisions, not raw secrets. A trace can safely say that a session cookie was absent without printing the session value.
Can you explain “Cookies, headers, and request data” without reaching for the API reference?
Describe the main trade-off, one failure mode, and the decision you would make in a real project.