LW IT Solutions
« Blog Overview /Digital Marketing/Tutorials / Tutorial: JSON-LD That Search Engines Actually Read
This post in other languages:

Tutorial: JSON-LD That Search Engines Actually Read

Tutorial: JSON-LD That Search Engines Actually Read
Contents
  1. The Two Lines That Decide Everything
  2. Four Mistakes That Produce No Error
  3. Article: The One Mandatory Field, and the Four That Matter
  4. FAQPage: The Rule That Reaches Into the Page
  5. Product: Price, Currency, Availability
  6. Checking Before It Goes Live

Structured data has no error state that anyone notices. A page carrying a relative image path, a date in local notation or a price with a currency symbol is served exactly like a correct one, ranks exactly like a correct one, and simply never receives the rich result it was written for. The markup is there, the crawler reads it, and nothing happens.

That makes structured data a maintenance problem rather than a writing problem. The mistakes are mechanical, they repeat across every page built from the same template, and a single wrong character in a field no visitor ever sees decides whether a listing shows a rating or a bare blue link. What follows is the chain a piece of markup has to pass through, and the four places where it usually drops out.

Four stages a piece of JSON-LD passes through - parsing, type recognition, mandatory fields and agreement with the visible page - with the markup that drops out at each stage
Four stages, four ways to fall out: nothing here reports an error, the rich result simply stays away.

The Two Lines That Decide Everything

Before a single property is read, two fields decide whether the block is looked at at all. @context has to point at https://schema.org; without it the object is a piece of JSON without a vocabulary, and every property in it means nothing. @type then names the thing being described. Its spelling is case sensitive: Article is a type, article is not, and the difference produces no warning anywhere.

Where several objects belong to one page – an article, its author and the breadcrumb trail – they can sit in one block under @graph or in separate script elements. Both work. What does not work is two blocks describing the same thing differently, because the parser has no rule for deciding which of them is meant.

Four Mistakes That Produce No Error

These four account for most of the markup that validates and still shows nothing. They share one trait: the field involved is invisible to visitors, so nobody notices it is wrong.

Written like this What happens What it has to be
"image": "/img/a.jpg" The path is never resolved, the image counts as missing, and with it the most visible part of the result. An absolute URL including the scheme.
"datePublished": "26.08.2026" The field is dropped. An article without a publication date loses its date in the listing. ISO 8601: 2026-08-26 or with a time and offset.
"price": "49,90 EUR" The offer is discarded as a whole – price and availability disappear together. A bare number with a dot, currency in priceCurrency.
"@type": "article" The type is unknown, so every property below it is read as an unspecified thing. Exactly Article, capital letter included.

The first three come from templates that fill the markup from the same variables as the page itself: The image path is relative because the template writes relative paths. The date is formatted because it is the formatted date that was already at hand. And the price carries its currency because that is how it is printed. Structured data needs the raw values, not the ones prepared for display.

Article: The One Mandatory Field, and the Four That Matter

An article needs a headline and nothing else. Everything that makes a result look like a result is optional, which is why so much markup passes the test and shows nothing.

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Article",
  "headline": "JSON-LD that search engines actually read",
  "description": "Why structured data fails without an error message.",
  "image": ["https://www.example.com/images/json-ld.png"],
  "author": { "@type": "Person", "name": "Lukas Wojcik" },
  "datePublished": "2026-08-26",
  "dateModified": "2026-08-26",
  "mainEntityOfPage": { "@type": "WebPage", "@id": "https://www.example.com/blog/json-ld/" }
}
</script>

Four details decide whether this markup earns anything. The headline is cut off beyond roughly 110 characters, so a title built from the page title plus the site name loses its ending. The author belongs in an object with a @type. A bare string is accepted, but it says nothing about whether a person or an organisation wrote the piece. dateModified must not lie before datePublished, a combination that appears whenever a migration writes the import date into one of the two fields. And the image should exist in more than one aspect ratio, because the layout that a result ends up in is not the one the markup asks for.

FAQPage: The Rule That Reaches Into the Page

An FAQ block is the one type whose validity depends on something outside the markup: every question and every answer has to be visible on the page itself. Markup describing an accordion that never opens, or questions that exist only in the JSON, counts as misleading rather than incomplete – and that is a manual action, not a missing feature.

Since 2023 the FAQ rich result itself is shown almost exclusively for authoritative government and health sites, so for most pages the visible reward is gone. The markup is still worth writing, only for different consumers: internal search, the assistants that read a page to answer a question, and every downstream system that would otherwise have to guess which part of the text is a question. Whoever expects the star-and-arrow listing from it will be disappointed; whoever wants a machine-readable question and answer pair gets exactly that.

Product: Price, Currency, Availability

A product without an offers block is a product without a price, and a price is the only reason a product result exists.

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Product",
  "name": "Compact PoE switch, 8 ports",
  "image": ["https://www.example.com/images/switch.png"],
  "brand": { "@type": "Brand", "name": "Example" },
  "offers": {
    "@type": "Offer",
    "price": "149.00",
    "priceCurrency": "EUR",
    "availability": "https://schema.org/InStock",
    "url": "https://www.example.com/switch/"
  }
}
</script>

The availability field takes a schema.org address, not the word behind it: InStock on its own is not a value. Where an aggregateRating is added, it needs both a ratingValue and a count – one without the other is dropped, and a rating that appears on the page but not in the markup is worth nothing to the listing. Ratings that a page cannot show, on the other hand, must not appear in the markup at all.

Checking Before It Goes Live

Three checks catch nearly everything, and they answer different questions. A structural check reads the block on its own: are the mandatory fields there, is the date an ISO date, is the price a number. The Rich Results Test then says whether Google recognises a type at all, which is the only place where a lowercase @type becomes visible. And the enhancement reports in Search Console show what happens across the whole site over time, which is where a template error surfaces as several hundred identical warnings rather than one.

What none of them answers is whether a result will be shown. Valid markup is a condition, not a claim: Google decides per query and per page whether a rich result appears, and a correct block that produces nothing is the normal case rather than a fault. The reason to write structured data is the one that survives that decision – a page whose statements are readable by machines, at a moment when more and more of them are doing the reading.

Lukas Wojcik

Lukas Wojcik

Systems architect and technology enthusiast specializing in scalable tracking solutions, GMP Stack (GA4 & GTM), and robust backend architectures. Advocate for clean code and privacy-first design.

Get in Touch

Briefly describe your project or inquiry for a tailored response. This site is protected by reCAPTCHA.

ALL ARTICLES & CATEGORIES

CCTV

Follow this category by RSS

Data Privacy

Follow this category by RSS

Digital Analytics

Follow this category by RSS

Digital Marketing

Follow this category by RSS

IT & Networks

Follow this category by RSS

Raspberry PI

Follow this category by RSS

Smart Home

Follow this category by RSS

Web Development

Follow this category by RSS

Wordpress Hacks

Follow this category by RSS