Information Retrieval · Search UX

Structured Result Cards and the Schema That Feeds Them

How a search interface renders a recipe, event, or product as a structured card rather than a text snippet, and how the structured data gets from a page into the index.

The same result list that shows two lines of highlighted text for a news article shows, for a recipe, a card with a star rating, a cook time, and a calorie count, and for an event a card with a date and a location. Those cards are not extracted from the page text by a summarizer; they are rendered from structured data the page’s publisher embedded in the HTML, parsed at crawl time into typed fields, and stored alongside the document in the index. The mechanism spans three layers: an annotation vocabulary, a parser, and a card renderer.

The annotation vocabulary

The dominant vocabulary is Schema.org, a shared set of types and properties maintained as a public hierarchy. A recipe page marks itself as a Recipe type and populates properties such as cook time, rating, and ingredient. A product page marks a Product with an offer, a price, and an availability. The vocabulary’s value is that it is a contract between publisher and search engine: the publisher states facts in a machine-readable form, and the engine trusts those statements as ground truth rather than attempting to infer them from prose.

The annotation is embedded in the HTML in one of several serializations, of which JSON-LD, a script element containing a JSON object with the typed properties, is the most widely used because it sits in one place and does not require the markup itself to be rewritten. RDFa and Microdata are the alternative serializations that annotate the visible HTML elements directly, attaching type and property attributes to the tags that render the content. All three encode the same facts; they differ in where the facts live relative to the visible text.

Parsing and validating the annotations

At crawl time the engine extracts the annotations and reconciles them against the vocabulary. The parser resolves the types and properties against the Schema.org hierarchy, coerces the values to the expected types, and applies constraints: a rating is a number in a bounded range, a date is a specific format, a cook time is a duration. The validation step is where the trust boundary is drawn, because a publisher can state any value, and a card that displays a fabricated rating damages the result list.

The coercion step is where most malformed annotations are caught. A rating stated as the string “4.7 out of 5” must be parsed to the number 4.7, and a rating stated as 47 with no scale is either rejected or normalized against the vocabulary’s expectation that a rating is on a scale with a stated maximum. The vocabulary makes the scale explicit through a related property, the best and worst rating, and a parser that ignores that scale can render a card whose rating means the wrong thing. The same kind of coercion applies to durations, where the ISO 8601 form PT45M must be recognized as forty-five minutes rather than stored as a raw string, and to dates, where the vocabulary expects a specific format and a publisher that writes a free-text date is rejected rather than guessed at.

This is why structured results carry an adversarial element absent from plain snippets. A snippet is verbatim text, and the worst a publisher can do is influence which window is shown. A structured card displays a claimed fact as a fact, so the engine filters annotations against the vocabulary’s expectations and, in some cases, against signals gathered elsewhere, such as an aggregate of ratings across sources. The near-duplicate grouping machinery is a natural companion here, since structured fields also feed the disambiguation of which of several similar-looking pages is the canonical one.

The JSON-LD serialization makes the contract concrete. A minimal recipe annotation is a script element whose content is a JSON object naming the type and the typed properties:

{
  "@context": "https://schema.org",
  "@type": "Recipe",
  "name": "Sourdough Loaf",
  "cookTime": "PT45M",
  "recipeYield": "1 loaf",
  "ratingValue": 4.7
}

The engine’s parser reads this at crawl time, resolves Recipe against the Schema.org hierarchy, and stores cookTime as a duration, ratingValue as a number, and recipeYield as a string. The card renderer then lays out exactly these fields under a recipe template. The same object marked @type Event with a different set of properties renders under the event template, which is why the type, not the page’s prose, decides what the card looks like.

Rendering the card and its failure modes

The card renderer maps the typed fields to a fixed visual template per type: a recipe template shows rating, time, and calories; an event template shows date and place. The template is fixed because the fields are known in advance, which is what distinguishes a card from a snippet: a snippet must handle arbitrary text, a card lays out a known set of typed values. The cost is rigidity. A page that omits a field leaves a gap in the card, and a page that marks itself as the wrong type renders under the wrong template or not at all.

The template also forces a decision about which fields earn a place on the card. The vocabulary defines far more properties than a single card can show, so the renderer selects a small set per type, and that selection is a presentation judgement about what the reader needs to decide before clicking. A recipe card showing the rating and the time but not the yield is making a claim about which attributes drive the click; a different selection would produce a different click pattern, which is why the field selection, like the choice of representative in near-duplicate grouping, is a ranking-adjacent decision made at the presentation layer.

Two failure modes dominate. The first is over-claiming: a publisher marks a page as a Recipe when it is an advertisement, and the card lends it an authority the prose does not earn. The second is staleness: the structured data is cached at crawl time, so a price or an availability stated in the annotation can diverge from what the page shows when the reader arrives, a divergence that is far more visible in a card with a price than in a two-line text snippet. The mitigation is a shorter cache lifetime for volatile fields and a revalidation on render, neither of which is free.

Structured results are the point where a search interface stops summarizing and starts asserting. The vocabulary is a shared contract, the parser is a trust boundary that validates claims against a type hierarchy, and the renderer is a fixed template that turns typed fields into a card. The whole stack exists because some facts, a rating, a price, a date, are worse off when compressed into prose, and better off when stated in a form the engine can carry intact from the page to the result list.

That form is also what connects structured cards back to the snippet mechanism at the start of this cluster. A card and a snippet are two answers to the same question, how to present a matched document in two lines, and they differ only in what they trust. The snippet trusts the document’s prose and extracts a window of it; the card trusts the publisher’s structured claims and renders typed fields. When both are present, the interface must choose, and the choice is normally to show the card for types whose facts benefit from structure and the snippet everywhere else, a division of labour between the two extraction paths rather than a hierarchy.

References

  1. Schema.org full hierarchy — Schema.org
  2. RDFa 1.1 Primer — W3C