Read client metadata
A Server Component needs to personalize output from the browser or proxy request.
Next.js 16+ · Module
next/headers provides the asynchronous headers function for reading incoming request headers. It returns a read-only Web Headers object and uses request-time data, so calling it opts the route into dynamic rendering.
Import the asynchronous headers function from next/headers and await it in a Server Component, Route Handler, or Server Action. The resulting read-only Web Headers object supports standard methods such as get; because the values are request-specific, using it makes the route dynamically rendered.
import { headers } from 'next/headers'
const headersList = await headers()A Promise that resolves to a read-only Web Headers object.
import { headers } from 'next/headers'
export default async function Page() {
const requestHeaders = await headers()
const userAgent = requestHeaders.get('user-agent')
return <p>User agent: {userAgent ?? 'unknown'}</p>
}Reads the incoming User-Agent header in a Server Component and renders it.
A Server Component needs to personalize output from the browser or proxy request.
A Route Handler needs to inspect authorization or forwarding information before producing a response.
A server-side operation needs request-specific values while retaining the standard Web Headers API.
headers is an asynchronous function from next/headers that reads incoming HTTP request headers. It returns a read-only Web Headers object, so standard methods such as get can inspect values but cannot mutate outgoing headers.
Follow-up: How would you send a response header instead? Return a Response, or another response object, constructed with the desired headers rather than modifying the value returned by headers().
Call await headers() inside an async Server Component, Route Handler, or Server Action, then use methods such as get. The function takes no parameters.
Follow-up: Why can this affect caching? Its values are unavailable before the request, so using it opts the route into dynamic rendering.
The API is request-time because incoming header values cannot be known ahead of the request. Consequently, a route that uses it is rendered dynamically rather than being treated as fully static.
Follow-up: Can the returned object set a cookie or response header? No; it is read-only, so response metadata must be set on the returned response.
cookiesdraftModeRoute HandlersServer ComponentsRequest-time APIs