Structured Data & JSON-LD
structured data & json-ld structured data via json-ld encodes entity semantics for google search rich resu structured data (json-ld) tells
Introduction
Structured data (JSON-LD) tells Google Search explicit entity semantics — Product, Article, FAQ, BreadcrumbList — enabling rich results and clearer entity understanding. Invalid or misleading schema triggers manual actions and stripped enhancements.
Business problem
Rich results lift CTR 20–40% on eligible queries. Marketing wants stars and FAQ accordions; engineering must ship valid JSON-LD tied to visible on-page content — Google penalizes markup that doesn't match the page.
- Compliance: Fake Review schema on products without visible reviews → manual action.
- Maintenance: CMS-driven JSON-LD drifts from rendered HTML after redesigns.
- Multi-type: Conflicting @type graphs confuse Rich Results Test.
Why this feature exists
Schema.org vocabulary plus JSON-LD format (W3C) lets search engines parse entities without microdata clutter in body HTML. Google recommends JSON-LD in <script type="application/ld+json"> for maintainability.
- Microdata/RDFa: Still valid but couple markup to presentation — harder in component frameworks.
- JSON-LD: Separate graph in head or body — easier to generate server-side and validate in CI.
- Rich result types: Google documents supported types — not all schema.org types get enhancements.
Browser internals
Googlebot extracts JSON-LD scripts during parse — does not require JS execution for static script blocks. Multiple JSON-LD blocks merge into one graph if @id links entities.
- Parser: Invalid JSON silently drops entire block — no partial credit.
- Dynamic injection: Client-rendered JSON-LD may miss first crawl wave.
- @graph: Array of entities for Organization + WebSite + Product on same page.
Rendering workflow
Visible content parity: Google requires structured data to reflect content users see. Hidden JSON-LD for reviews not on page violates guidelines. SSR JSON-LD alongside matching HTML satisfies parity at first paint.
- Product: price, availability, name, image must match DOM.
- FAQ: Each Question/Answer must appear on page.
- Breadcrumb: Must mirror visible breadcrumb nav.
Feature deep dive
JSON-LD patterns for common Google Search enhancements:
- Product: name, image, description, sku, offers (price, priceCurrency, availability).
- Article: headline, datePublished, author, image — for Top Stories eligibility rules.
- FAQPage: mainEntity array of Question with acceptedAnswer.
- BreadcrumbList: itemListElement with position and item URL.
<script type="application/ld+json">{"@context": "https://schema.org","@type": "Product","name": "Trail Runner X","image": ["https://cdn.example.com/shoe-800.jpg"],"description": "Waterproof trail shoe.","sku": "TRX-42-BLK","offers": {"@type": "Offer","url": "https://shop.example.com/trail-runner-x","priceCurrency": "USD","price": "129.99","availability": "https://schema.org/InStock"}}</script>
Accessibility analysis
Structured data does not replace accessible HTML — FAQ rich results still need keyboard-operable accordions on page. BreadcrumbList schema should match a visible <nav aria-label="Breadcrumb">.
- Hidden content: Off-screen FAQ text for schema only fails guidelines and WCAG 1.3.1.
- Reviews: Visible review text with proper heading structure — not schema-only.
SEO impact
Primary rich-result lever. Monitor Search Console → Enhancements for Product, FAQ, Breadcrumb errors. Fix validation before expecting CTR lift.
- Rich Results Test: Pre-launch validation for every template change.
- Merchant Center: Product feed must align with on-page Product JSON-LD.
- Deprecation: Google retires rich result types — subscribe to Search Central blog.
Security considerations
JSON-LD injection via CMS could embed misleading offers or phishing URLs in SERP snippets. Sanitize all string fields; allowlist @type values in CMS schema.
- XSS in script: JSON-LD is script content — never interpolate raw user HTML into JSON strings unescaped.
- URL fields: Validate offer URLs stay on your domain.
Performance impact
Small JSON-LD blocks (<2KB) negligible for LCP. Avoid megabyte graphs — split Organization sitewide schema from page-specific types via @id references.
- Inline vs external: Inline in HTML avoids extra request — preferred for critical Product schema.
- Duplicate graphs: Same Product twice increases parse work marginally — dedupe in template.
Real production example
Validated pipeline — generate JSON-LD server-side, validate in CI:
- @id linking: "#product" in page graph references Organization "#org" sitewide.
- Monitoring: Alert on Search Console enhancement error count > 0.
// ci/validate-jsonld.mjsimport Ajv from "ajv";import schema from "schema-dts/Product";const ld = JSON.parse(html.match(/ld\+json">([\s\S]*?)<\/script>/)?.[1] ?? "{}");if (ld.offers?.price !== visiblePriceFromHtml) {throw new Error("JSON-LD price mismatch — Google manual action risk");}
Enterprise usage
Marketplace with 2M SKUs: JSON-LD generated from PIM feed same source as PDP HTML — single source of truth. Invalid offers blocked at publish.
- Localization: priceCurrency and inLanguage per locale in JSON-LD.
- A/B tests: Do not change schema @type mid-experiment without validation.
Common production failures
Manual actions from aggregateRating on products with zero on-page reviews. FAQ schema on marketing landing with no visible Q&A — enhancements removed site-wide.
- Stale price: JSON-LD $99, DOM $129 after flash sale — Merchant Center disapproval.
- Broken JSON: Trailing comma in template — entire block ignored, no rich results.
Architecture review questions
- Does every JSON-LD field match visible on-page content?
- Is JSON-LD valid JSON validated in CI (Rich Results Test API)?
- Are unsupported @types removed to avoid false expectations?
- Is JSON-LD in initial HTML for critical product/article pages?
- Are enhancement errors in Search Console at zero for launch?
Hands-on project
Project: Add Product + BreadcrumbList JSON-LD to a PDP template with CI test asserting price/name parity with DOM.
- Validate: Google Rich Results Test + schema.org validator.
- Document: Which fields come from PIM vs CMS.
Interview questions
Why JSON-LD over microdata for a React SSR app?(Advanced)
JSON-LD decouples entity graph from component markup — generate one object server-side, validate in CI, inject in head. Microdata couples attributes to DOM nodes — fragile when components refactor and harder to unit test.
Follow-up: How do you link Organization and Product graphs?
What causes Google to remove rich results after launch?(Advanced)
Content mismatch (schema claims reviews/FAQ not visible), invalid required properties, policy violations (self-serving reviews), or site-wide quality issues. Fix visible content first, then schema.
Follow-up: Difference between Rich Results Test pass and actually showing stars?
Design schema governance for 50 teams publishing pages.(Advanced)
Allowlist @types per template; CMS fields map to schema properties; CI validates JSON + parity with HTML snapshot; Search Console enhancement dashboard owned by platform SEO; breaking changes versioned with migration guide.
Follow-up: How handle user-generated review schema?
Try it yourself
Edit the HTML, CSS, or JS panels — the preview updates as you type.
Try it yourself
Summary
Structured data via JSON-LD encodes entity semantics for Google Search rich results — staff engineers generate it server-side, validate against visible HTML in CI, and monitor enhancement reports to prevent manual actions.