Skip to main content
短.be

Content Negotiation

A mechanism in which the client and server negotiate the optimal content format (language, media type, encoding) through HTTP headers.

Aug 24, 2026 · About 2 min read

Redirect

Content negotiation is the HTTP mechanism by which a client (browser) and server agree on the best representation of a requested resource. The same URL can return different content depending on the user's language preference, device capabilities, or supported formats.

Negotiation happens primarily through HTTP request headers. The Accept header specifies supported media types (text/html, application/json, etc.), Accept-Language specifies preferred languages (ja, en-US, etc.), and Accept-Encoding specifies supported compression methods (gzip, br, etc.). Any of these headers can carry q values to express preference: Accept-Encoding: br, gzip;q=0.8 asks for br first and accepts gzip otherwise. Whenever a server varies its response based on such headers, it has to name them in a Vary header. Omitting Vary: Accept-Language lets a cache or CDN serve the first language it received to everyone who follows.

Content negotiation intersects with shortened URLs in multilingual sites. A single short link can redirect to a Japanese or English page based on the browser's language setting. However, from an SEO standpoint, having distinct URLs per language with hreflang tags is preferred, because content negotiation can prevent search engines from correctly indexing each language version. Google likewise recommends a separate URL for each language version instead of switching on cookies or browser settings, and asks site owners to avoid redirecting visitors automatically from one language version to another, since such redirects can stop both people and search engines from reaching every version. Google's crawler also issues requests without an Accept-Language header, so a site that switches on that header alone exposes only its default language to crawling. Adapting content from IP-based location is discouraged for the same reason.

In API design, content negotiation is equally important. A URL shortening API that returns JSON or XML depending on the Accept header is a common pattern. Offering several representations of the same resource lets each client pick a format it can handle. The algorithm that chooses among them is not defined by HTTP, though; it is left to the server implementation. Whether an unsupported request yields 406 (Not Acceptable) or simply the default representation is an implementation decision as well.

Two types of content negotiation exist: server-driven (the server inspects request headers and decides) and agent-driven (the server presents options and the client chooses). HTTP calls the first proactive negotiation and the second reactive negotiation. Server-driven negotiation dominates in practice, but its trade-off is that a decision inferred from headers is always somewhat arbitrary. Agent-driven negotiation never caught on because the format of the page listing the options is not specified, which prevents the choice from being automated, and because it costs one extra round trip before the real resource arrives.

Share on XHatena

Was this article helpful?

Related Terms

Related Articles

FAQ

Should I use content negotiation to switch languages automatically?
It improves user experience, but be cautious about SEO. Search engines may not index each language version correctly. Using separate URLs per language with hreflang tags is the recommended approach. Keep in mind that Accept-Language only reflects a browser or system setting and does not reliably express the language the visitor wants to read right now. If you do detect it, limit that to entry pages and always give visitors a way to switch away from the language you chose.
How do I implement content negotiation in an API?
Parse the Accept header of the request. Return JSON for application/json and XML for application/xml. An unsupported format has no single prescribed handling: replying with HTTP 406 (Not Acceptable) and ignoring the header to return the default format are both permitted. Many implementations prefer the default response, because clients find some answer easier to work with than none. Name the header you inspected in the response as Vary: Accept.
How is the Accept-Language header set?
It is sent automatically based on the browser's language settings. For example, a browser configured for Japanese sends something like "Accept-Language: ja,en-US;q=0.9,en;q=0.8," listing languages with priority weights.

Put the terms to work

Shorten a URL for Free