Structured data: fixing JSON-LD and qualifying for rich results

How JSON-LD tells search engines what a page is about, how to fix a block that doesn’t parse, and which rich results it can lead to.

Structured data describes a page in a form machines can read: this is a product with this price, an event on this date, an article by this author. Search engines use it to understand the page, and Google uses it to decide whether a result can show extras, such as a price, a rating, or a breadcrumb path.

It’s optional. A page without it can still appear in search with a normal result. But several result types depend on it, and a block with one syntax error is ignored entirely.

What SignalDNS checks

We read the page’s HTML before JavaScript runs:

  • JSON-LD: each <script type="application/ld+json"> block, up to 20. We parse each one and list every typed object in it, including nested objects and items in @graph, with the properties each sets. Empty blocks are skipped, and a block cut off by our 2 MiB limit is left out rather than called broken.
  • Microdata: the itemtype of each element that has one. We name the types, but don’t read their properties.
  • RDFa isn’t read.

That answers two questions. “Can search engines read its structured data?” covers whether each JSON-LD block parses and which types it describes. “Which search features could it get?” compares the types with the properties Google requires for each result type. We check that the properties are present, not that their values are right. A page with no structured data isn’t flagged.

What JSON-LD looks like

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Organization",
  "name": "Example Ltd",
  "url": "https://www.example.com/",
  "logo": "https://www.example.com/images/logo.png"
}
</script>
  • @context says the names come from schema.org.
  • @type says what the object is. Use the type Google documents for the result you want.
  • The other keys are properties. A value can be text, a number, a list in [ ], or another object with its own @type.
  • To describe several things, use several blocks, or one block with a @graph list.

Google recommends JSON-LD, though it reads microdata and RDFa equally well. Its guidelines say to mark up only content people can see on the page; markup that breaks them can keep a page from getting a rich result.

A JSON-LD block doesn’t parse

The block isn’t valid JSON, so search engines skip all of it, along with everything it describes. SignalDNS marks this as a problem. The result shows the parser’s error and, where it can, the types the block was meant to describe, read from its text, so you can tell which block it is. Search features that depend on it show as Blocked.

JSON is stricter than JavaScript. The usual causes:

  • A trailing comma after the last property or list item, as in "name": "Example Ltd",}.
  • A missing comma between two properties.
  • A double quote inside a value that isn’t escaped. Write \" inside a string: "name": "The \"Classic\" Shoe".
  • Curly quotes or single quotes around keys and values. JSON needs straight double quotes, and word processors and some editors replace them.
  • HTML entities, such as &quot; or &amp;. Text inside a script tag isn’t decoded, so &quot; stays six characters and can’t stand in for a quote.
  • Comments. JSON has none, so // and /* */ break the block.
  • A line break inside a value. JSON needs it written as \n.
  • Text a CMS or template inserted: a <p> or <br> from a rich text editor, a shortcode that didn’t run, or an empty template variable that leaves "price": ,.
  • </script> inside a value, which ends the block early. Write it as <\/script>.

How to fix it:

  1. Paste the page’s address or the block into the Schema Markup Validator or Google’s Rich Results Test to find the error.
  2. Fix it where the block is made, in the plugin, theme, or template, so the fix holds for every page that uses it.
  3. If you build the block in code, create an object and serialize it rather than joining strings. In JavaScript, JSON.stringify(data).replace(/</g, '\\u003c') also stops a < in a value from ending the script, as the Next.js docs show.
  4. Audit the page again.

Which types the page describes

We list the types we found, such as Organization, BreadcrumbList, or Product, up to five. This is OK when we find types, and a note, not counted, when there are none.

  • JSON-LD types come with the properties each object sets, which the search features check uses.
  • Microdata types are named, but we don’t read microdata properties, so we can’t check search features from them. Google reads microdata, so use the Rich Results Test to check those.
  • No structured data is a note, not a finding. Pages don’t need it. We don’t read RDFa, so a page that uses only RDFa shows none here.

The types and properties come from the schema.org vocabulary, which has many more than Google uses. For Google Search, Google’s documentation is what counts: it lists the types and properties each result type reads. Other types may still be useful to other search engines and tools.

Search features need more markup

For each result type a page’s markup points to, we check the properties Google lists as required, on the same object. When a page repeats a type, the object missing the fewest decides. Each feature shows one of these:

  • Eligible: the required properties are there. Google says correct markup makes a page eligible, not that the feature will show.
  • Incomplete: a required property is missing, and the result names it. SignalDNS marks this as needing attention.
  • Blocked: the block with that type doesn’t parse. See above.
  • Not marked up: a suggestion, not counted.
  • Retired: Google no longer shows this result type.

What each feature needs, from Google’s page for it:

  • Product results: Product or ProductGroup with name, and one of offers, review, or aggregateRating, as for product snippets. Merchant listings, for pages where people can buy, also need image and an Offer.
  • Breadcrumb trail: BreadcrumbList with itemListElement, a list of ListItem objects. Google shows it on desktop. Breadcrumb
  • Article details: Article, NewsArticle, or BlogPosting. Google requires no properties, and recommends headline, image, datePublished, dateModified, and author. Article
  • Video results: VideoObject with name, thumbnailUrl, and uploadDate. Video
  • Event listings: Event with name, startDate, and location. Event
  • Job listings: JobPosting with title, description, datePosted, hiringOrganization, and jobLocation, or applicantLocationRequirements for a fully remote job. Job posting
  • Business details: LocalBusiness, or a subtype we recognize such as Restaurant, Store, or Dentist, with name and address. Local business
  • Recipe results: Recipe with name and image. Recipe
  • Organization logo: Organization or Corporation with logo. Google’s organization markup has no required properties, but logo is what tells Google which logo to show, and it must be at least 112 × 112 px. Organization
  • FAQ results: FAQPage, marked Retired. Google’s changelog says FAQ rich results stopped appearing on May 7, 2026, and their documentation was removed in June 2026. Search Central updates
  • How-to results: HowTo, marked Retired. Google removed its how-to documentation in September 2023, because the rich result no longer shows on desktop or mobile. Search Central updates

Two suggestions are never counted:

  • Review stars, for a Product without aggregateRating or review. If the page shows reviews, marking them up lets Google consider stars. Google’s review snippet guidelines say the reviews and rating must be visible on the page.
  • Breadcrumb trail, for any page other than the home page without BreadcrumbList.

How to fix it: add the missing property to the same object as the type, following Google’s page for that result type, then test the page in the Rich Results Test.

Setting it up in your CMS or framework

What we can’t tell from outside

We read the HTML before JavaScript runs. Google can read JSON-LD that scripts add, so markup injected by a tag manager or a client-side app may work for Google and still not show here. We check that required properties exist, not that their values are valid, such as a real date or an image that loads. We don’t read microdata properties or RDFa. And we can’t check Google’s quality guidelines, such as whether the markup matches what’s on the page. Search Console’s rich result reports show what Google found and any errors.

Sources

Last reviewed .