Tags: web-dev concept

Structured Data

Date: 2026-08-16


Machine-readable markup declaring what a page’s content means — this is a product, this is its price, this is its rating. It doesn’t improve rankings directly; it makes a page eligible for richer presentation, and increasingly it’s what non-visual consumers of your site read.


What it is

Structured data is markup using a shared vocabulary — in practice, schema.org — that states the entities on a page and their properties.

Three encodings exist; JSON-LD is the one to use, because it sits in a script tag rather than being interleaved with your markup, which means it survives template changes and can be generated server-side without touching the DOM.

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Product",
  "name": "Merino Wool Socks",
  "sku": "4471",
  "brand": { "@type": "Brand", "name": "Example" },
  "offers": {
    "@type": "Offer",
    "price": "24.00",
    "priceCurrency": "GBP",
    "availability": "https://schema.org/InStock",
    "url": "https://shop.example.com/products/merino-wool-socks"
  }
}
</script>

What it’s for

  • Rich results — the enhanced presentation in search: price, availability, ratings, breadcrumbs, FAQ accordions
  • Disambiguation — telling an engine that “£24.00” is a price rather than a number on a page
  • Machine consumption — a growing share of what reads your site isn’t rendering it visually. Structured data is the part that survives that

It is not a ranking factor in itself. It affects eligibility for presentation, which affects click-through rate, which is a different mechanism. Anyone promising rankings from schema markup is overselling it.

[CHECK: which rich result types are currently supported, and their requirements, change regularly — verify against Google’s search gallery documentation before building for a specific result type.]

The types worth having on a retail site

TypeOnGets you
Product + OfferProduct pagesPrice, availability, currency in results
AggregateRating / ReviewProduct pages with reviewsStar ratings
BreadcrumbListEverywherePath display instead of a raw URL
OrganizationSite-wideLogo, name, contact, social profiles
WebSite with SearchActionHomepageSitelinks search box
FAQPageGenuine FAQ contentExpandable answers, where still eligible
ItemListCategory pagesCarousel eligibility

Rules that hold regardless of the vocabulary

  • It must match the visible page. Marking up a price, rating or availability that a user can’t see is a policy violation and can earn a manual penalty. This is the rule that gets broken, usually by good intentions — a rating averaged differently in markup than on the page
  • Generate it from the same data as the page. Hand-maintained JSON-LD drifts within a month. It should come from the same source as the rendered content, so drift is structurally impossible
  • Put it in the server response. Injected client-side, it’s invisible to non-rendering crawlers — Rendering and SEO
  • Complete beats clever. A Product missing price or availability may not be eligible at all. Fill required fields before adding optional ones
  • One entity per thing. Duplicate or conflicting blocks on the same page get ignored
  • Currency and price as strings, formatted plainly. "24.00" and "GBP", not £24

Where it goes wrong

  • Marking up review ratings the site doesn’t display, or aggregating across variants in a way the page doesn’t show
  • Stale availability — markup says InStock while the page says sold out, because they’re generated from different sources
  • Marking up every page as FAQPage to chase an expanded result. Eligibility for these has been narrowed before and will be again
  • Category pages marked as Product. A listing is an ItemList, not a product
  • Client-side injection, so half your consumers never see it
  • Never validating. Schema errors are silent — nothing breaks visually, the page just stops being eligible

Validating

  • Google’s Rich Results Test for eligibility of a specific URL
  • Schema.org validator for vocabulary correctness, which is a different question
  • Search Console → Enhancements for errors across the site at scale, and this is where you’ll notice a template change broke it
  • Add it to a pre-launch crawl — a site crawler can extract and validate JSON-LD in bulk, which catches template-level breakage before it ships

The durable principle underneath all of this: structured data is a contract stating your page means what it appears to mean. Keep it generated from the same source as the visible content, and most of the failure modes above can’t occur.