JSON-LD
The recommended syntax for embedding structured data in a page's <head>.
JSON-LD (JavaScript Object Notation for Linked Data) is a lightweight, JSON-based syntax for expressing structured data — most commonly schema.org markup — embedded in a page's HTML as a discrete `<script type="application/ld+json">` block, separate from the page's visible content and markup.
It is Google's explicitly recommended syntax for structured data, ahead of the two older alternatives, microdata and RDFa, both of which require interleaving structured-data attributes directly into visible HTML elements — a pattern that is harder to generate programmatically, easier to break accidentally during template changes, and harder to validate cleanly.
Because a JSON-LD block is a self-contained object independent of the surrounding markup, it can be generated dynamically from the same underlying data source (a CMS field, a database record, an API response) that drives the visible page content, which is both its main practical advantage and the reason well-built JSON-LD tends to stay accurate over time in a way hand-maintained microdata often does not.
A single page can contain multiple JSON-LD blocks, and multiple entity types can be expressed either as separate script blocks or combined within a single `@graph` structure — both are valid, though a single well-organised `@graph` is generally easier to maintain and reason about on pages describing several related entities (for example, an Organization, a LocalBusiness, and a set of Person entities for staff).
How JSON-LD is structured and parsed
A valid JSON-LD block declares a `@context` (almost always `https://schema.org`), one or more `@type` declarations identifying the entity type being described, and a set of properties matching that type's schema.org definition — `name`, `address`, `openingHours` for a `LocalBusiness`, for instance.
Search engine parsers read the JSON-LD independently of the page's rendered DOM, which means the data is not subject to CSS display rules — a JSON-LD block is parsed whether or not any corresponding visible content exists, which is precisely why Google's guidelines require the declared data to match visible content, since the syntax itself provides no visual accountability check the way microdata's inline attributes loosely do.
Why JSON-LD matters more in 2026
As AEO and GEO strategies depend on structured data staying comprehensive and accurate across a growing number of page templates, JSON-LD's ability to be generated programmatically from the same source data as the visible page is a genuine operational advantage — it scales to hundreds or thousands of templated pages (location pages, product pages) without requiring per-page manual maintenance, which manually-authored microdata realistically cannot match at scale.
How to validate JSON-LD implementation
Use Google's Rich Results Test for the specific rich-result-eligible types, and the general Schema.org Validator (schema.org/validator, run by Google) for broader syntax and structural validation covering types outside the rich-result-eligible set.
Check the raw HTML source (not just the rendered DOM in DevTools) to confirm the JSON-LD block is actually present in what a crawler receives, particularly on client-side-rendered pages where server-side rendering or static generation of the JSON-LD block is required for reliable parsing.
Common JSON-LD mistakes
Invalid JSON syntax — a trailing comma, an unescaped quotation mark, mismatched brackets — causes the entire block to fail parsing silently, with no visible symptom on the page itself, which is why validation needs to be a deliberate, recurring step rather than an assumption.
Declaring a JSON-LD block only in client-side JavaScript without server-side rendering or static generation means some crawlers may never see it if their rendering budget or JavaScript execution doesn't reach that point — a real risk on JavaScript-heavy sites that render markup entirely client-side.
Duplicating conflicting information across multiple JSON-LD blocks on the same page (two different `Organization` blocks with different `name` or `address` values, for instance) creates ambiguity search engines have no clean way to resolve.
- Invalid JSON syntax causing silent, total parsing failure.
- Client-side-only rendering of JSON-LD not reaching all crawlers.
- Conflicting duplicate schema blocks on the same page.
- Declared properties that don't match visible page content.
A step-by-step JSON-LD implementation process
Identify the entity types relevant to each page template (LocalBusiness for a homepage, Product for a product page, FAQPage for a Q&A section) and map their required and recommended properties against the CMS or database fields that already hold that data.
Build the JSON-LD block to generate dynamically from those same underlying fields rather than hand-authoring static values, ensuring the markup stays accurate as the underlying data changes.
Ensure the block is present in the server-rendered or statically-generated HTML, not injected client-side only, and validate with both the Rich Results Test and Schema.org Validator before deploying to production.
Set up a recurring validation check (a scheduled crawl or monitoring script) to catch any future template change that accidentally breaks the JSON-LD syntax or introduces a content mismatch.
JSON-LD for local Austin-area service business sites
For a local business with multiple location or service-area pages, generating LocalBusiness JSON-LD dynamically from a single structured data source (rather than hand-writing a separate block per page) is the difference between schema that stays accurate as hours, pricing, or service areas change, and schema that quietly drifts out of date within months of launch.
How JSON-LD relates to schema and entity
JSON-LD is the delivery syntax; schema.org is the vocabulary being delivered; entity strength is the outcome a comprehensive, accurate, consistently-generated set of JSON-LD blocks across a site is a primary mechanism for building.
JSON-LD implementation checklist
| Present in server-rendered HTML | Required | Not client-side-only; must be in what a crawler actually receives. |
|---|---|---|
| Valid JSON syntax | 0 parsing errors | Verify via Schema.org Validator and Rich Results Test. |
| Content match | 100% match to visible page | Every declared property must reflect what's actually shown. |
| Generation method | Dynamic from CMS/data source | Preferred over hand-authored static blocks at scale. |
Frequently asked questions
- Why does Google recommend JSON-LD over microdata?
- JSON-LD is a self-contained script block separate from visible markup, making it easier to generate programmatically, less likely to break during template changes, and easier to validate cleanly than microdata or RDFa, which require interleaving attributes into visible HTML.
- Can I have multiple JSON-LD blocks on one page?
- Yes. A page can contain several script blocks for different entity types, or combine multiple entities within a single @graph structure — both are valid, though a well-organised @graph is often easier to maintain on pages describing several related entities.
- Why isn't my JSON-LD being picked up by Google?
- The most common causes are invalid JSON syntax causing silent parsing failure, the block being injected client-side only and not present in the server-rendered HTML crawlers receive, or a content mismatch between the declared data and what's visible on the page.
- How do I validate JSON-LD?
- Use Google's Rich Results Test for rich-result-eligible types, and the general Schema.org Validator for broader structural validation covering any schema.org type. Also check the raw HTML source directly to confirm the block is actually present server-side.
- Should JSON-LD be generated dynamically or hand-written?
- Dynamically, wherever possible — generating it from the same CMS or database fields that drive the visible page content keeps it accurate as that data changes, whereas hand-authored static blocks tend to drift out of sync over time.
A multi-location home services company hand-wrote a LocalBusiness JSON-LD block per location page. Six of eighteen locations had outdated opening hours in their schema after a scheduling change. Rebuilding the block to pull dynamically from the same CMS fields as the visible hours table eliminated the drift entirely.
Need this applied to your site?
We turn concepts like these into shipped work every week.
