Content Negotiation

Content negotiation lets a client request an alternative representation of a resource via the Accept header, without changing the URL.

When to reach for it

Use content negotiation when a client needs structured data instead of rendered HTML. Set the Accept header on a GET request to receive a different media type.

Supported media types

Accept value Response
text/html (default) The HTML document, after server-side processing
application/ld+json The document's microdata serialized as JSON-LD

When no Accept header is present, or when it does not match a supported type, HTML is returned.

Content negotiation applies to both full-document and selector requests.

JSON-LD serialization

When a client requests application/ld+json, the server extracts HTML Microdata from the rendered page and returns JSON-LD.

Context inference

The @context and @type are inferred from the itemtype attribute. When itemtype is a full URL, the base becomes @context and the type name becomes @type.

Given this HTML:

<div itemscope itemtype="http://schema.org/Person">
  <span itemprop="name">Alice</span>
</div>

The JSON-LD response is:

{
  "@context": "http://schema.org/",
  "@type": "Person",
  "name": "Alice"
}

For non-URL itemtype values, the full string is used as @type with no @context.

Multiple items

When a page contains multiple top-level itemscope elements, they are wrapped in a @graph:

{
  "@context": "http://schema.org/",
  "@graph": [
    { "@type": "Person", "name": "Alice" },
    { "@type": "Person", "name": "Bob" }
  ]
}

When all items share the same vocabulary, @context is hoisted to the top level. When items use different vocabularies, each item carries its own @context inside the @graph.

A page with a single top-level item returns a flat JSON-LD object without @graph.

Example

Request JSON-LD by setting the Accept header:

GET /content-neg-jsonld-test.html
Accept: application/ld+json
HTTP/1.1 200
Content-Type: application/ld+json; charset=utf-8

{
  "@context": "http://schema.org/",
  "@type": "Person",
  "name": "Alice"
}

Vary header

All responses include Vary: Accept so that caches distinguish between HTML and JSON-LD representations of the same URL.

Non-HTML resources

Content negotiation applies only to HTML resources. Requests for non-HTML resources (images, stylesheets, scripts) ignore the Accept header and return the resource unchanged.

See also