Schema.org Structured Data: How to Earn Rich Results
JSON-LD, the schema types that genuinely produce rich results, and the validation mistakes that block them — with ready examples for services, articles and FAQs.
Structured data is one of the few SEO tools with a predictable payoff: you add a few kilobytes of JSON and a week or two later your snippet looks different. The catch is that half the Schema.org vocabulary no longer produces any rich result at all, and plenty of guides still tell you to mark up everything. Below: which types genuinely work in 2026, how to embed JSON-LD correctly, ready examples for services, articles, FAQs and breadcrumbs, and why a validator can be green while your snippet stays plain.
2–14
days from adding markup to a changed snippet
4
types that cover most sites entirely
~3 KB
typical JSON-LD payload per page
0
direct ranking effect — appearance and clarity only
Which types genuinely produce rich results
Google has switched off several popular result formats in recent years, quietly invalidating a lot of published advice. The honest picture for 2026 splits into "changes how you look in results" and "helps a machine understand the page but shows nothing".
| Type | What it produces | Difficulty |
|---|---|---|
BreadcrumbList | A path instead of a raw URL — works almost everywhere | Low |
Product + Offer | Price, availability and rating in results and Shopping | Medium |
Article / BlogPosting | Date, author, image; improves odds in news surfaces | Low |
LocalBusiness | Hours, address and phone in the knowledge panel | Medium |
Organization | Logo and profiles in the knowledge panel; nothing in the snippet | Low |
FAQPage | Expanded snippet for authoritative sites only; nothing for the rest | Low |
JSON-LD: how to embed it properly
Schema.org supports three syntaxes — microdata, RDFa and JSON-LD. In practice there is one choice: JSON-LD. It stays out of your markup, it can be generated from the same data that renders the content, and it survives a redesign.
- Place the markup in a
<script type="application/ld+json">tag. Whether it sits in<head>or at the end of<body>is irrelevant — what matters is that it is in the HTML before rendering, not injected afterwards. - The markup must describe what is visible on the page. A price of $3,200 in JSON against $3,600 on the page is not a rounding issue, it is grounds for a manual action.
- Combine multiple entities inside a
@graphand link them by@id. Separate scripts also work, but they duplicate organisation data on every page. - Generate the JSON from real CMS fields rather than pasting it by hand. Hand-written markup survives until the first price or name change.
- Never mark up something that does not exist. An
aggregateRatingwith no reviews visible on the page is the commonest way to lose every rich result on a domain.
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [
{
"@type": "ListItem",
"position": 1,
"name": "Home",
"item": "https://example.com/"
},
{
"@type": "ListItem",
"position": 2,
"name": "Services",
"item": "https://example.com/services/"
},
{
"@type": "ListItem",
"position": 3,
"name": "Web development"
}
]
}Note the last element: the current page carries no item field. That single detail trips up most implementations — a validator accepts both variants, but when the final crumb links to itself the trail sometimes fails to render.
Ready examples for a service business
For a studio, agency, clinic or workshop the baseline is three things: the organisation described once for the whole site, a service described on each service page, and breadcrumbs everywhere. Here is a service page tied to the organisation through @id.
{
"@context": "https://schema.org",
"@graph": [
{
"@type": "Organization",
"@id": "https://example.com/#org",
"name": "WebEngine",
"url": "https://example.com/",
"logo": "https://example.com/logo.png",
"telephone": "+380000000000",
"address": {
"@type": "PostalAddress",
"addressLocality": "Kyiv",
"addressCountry": "UA"
}
},
{
"@type": "Service",
"name": "Next.js web development",
"serviceType": "Web development",
"provider": { "@id": "https://example.com/#org" },
"areaServed": { "@type": "Country", "name": "Ukraine" },
"offers": {
"@type": "Offer",
"priceCurrency": "USD",
"price": "1500",
"url": "https://example.com/services/web-development"
}
}
]
}Blog markup is simpler: BlogPosting with headline, datePublished, dateModified, author and image. The usual failure is a dateModified that updates itself every night when the site rebuilds. Google learns to discount those dates quickly — and discounts your genuine updates along with them.
Minimum markup set for a service site
Organizationwith logo, phone and address — once, present on every pageBreadcrumbListon every page below the homepageServicewithproviderandareaServedon service pagesBlogPostingon articles, with an honestdateModifiedFAQPageonly where the questions genuinely appear in the page copyWebSitewithpotentialActionfor search — only if site search actually works
Why the validator is green and the snippet is plain
This is the most common question after implementation. A validator checks syntax and required fields; it guarantees nothing about display. The real reasons, ordered by how often we see them:
- 1The page has not been recrawled. Rich results appear after the next crawler visit — two days to two weeks. You can nudge individual URLs with an indexing request, a handful per day.
- 2The type produces no rich result for your segment at all.
Organization,WebPageand breadcrumbs on a homepage change nothing visually by design. - 3The markup contradicts the content. If
Offersays in stock while the page shows a sold-out button, the enhanced snippet is withheld. - 4The markup is injected by client-side JavaScript after load. Google renders it formally; in practice, late and inconsistently. Serve JSON-LD in the initial HTML.
- 5The domain has a manual action for structured data spam. Check the Manual Actions report in Search Console — nine times out of ten the cause is invented ratings.
Structured data in AI-assisted search
Markup has stopped being purely a game about snippet appearance. The models that assemble answers in search extract entities from HTML — names, prices, authors, dates — and structured data is their most reliable source, because it needs no interpretation of prose.
- A clear
OrganizationwithsameAslinks to your profiles makes it far likelier a model names your company correctly instead of confusing it with a namesake. - An
authorwith a real name and an author page is one of very few machine-readable experience signals. An article with no author is anonymous to a model. - Prices and terms inside
Offerget quoted more accurately than the same figures in body copy — visible in how AI answers phrase them. FAQPagelost its rich result but remains a convenient format for extracting question-answer pairs. That alone is reason not to rip out markup you already have.
How to prepare content for search assistants in general is covered in our piece on optimising for AI search. Whether your markup reaches the crawler in the first place is easiest to establish inside a broader technical SEO audit.
Structured data does not raise rankings. It makes a page unambiguous to a machine — and an unambiguous page is easier to display and to quote.
Frequently asked questions about Schema.org markup
Does structured data affect search rankings?
Structured data is not a direct ranking factor, and Google has confirmed this repeatedly. The effect is indirect: a rich result takes up more space and earns a higher click-through rate, which over time supports the position. Expecting to jump from tenth to third on markup alone is unrealistic.
Should I use JSON-LD or microdata in the HTML?
JSON-LD is Google’s recommended format and far easier to maintain, because it does not depend on your markup structure. Microdata lives in tag attributes, and any redesign breaks it. There is no urgency in converting existing microdata, but build every new page on JSON-LD.
Can I mark up ratings if reviews are collected on a third-party platform?
No, and this is a frequent cause of manual actions. Google requires the values in aggregateRating to be visible on the page and to refer to a specific product or service, not the company in general. If reviews live in an external service, surface them on the page first, then mark them up.
How many schema types can go on a single page?
There is no technical limit, but only markup that describes the actual content is worth having. A typical service page needs three entities: organisation, service and breadcrumbs. Adding ten types "just in case" raises the chance of contradictions between them and gains nothing.
How quickly will a rich result appear after implementation?
Usually two days to two weeks — however long the crawler takes to revisit and process the page. Individual URLs can be sped up with an indexing request in Search Console. If nothing changes after a month and the markup validates, almost always no result format exists for that page type.
In short
- Visually,
BreadcrumbList,Product,ArticleandLocalBusinessstill work.FAQPageandHowTono longer produce rich results for most sites. - Use JSON-LD, generate it from CMS fields, and serve it in the initial HTML rather than through a client-side script.
- Markup must match visible content. Invented ratings are the shortest route to a manual action.
- Valid JSON does not equal a rich result: check both the Schema Markup Validator and the Rich Results Test.
- Structured data now serves two audiences — classic search results and citation inside AI-generated answers.
Related reading
SEO Checklist 2026: 60 Checks a Site Needs Before It Ranks
Not theory — the checklist we run every project through before launch. 60 items across six blocks.
AI Search Optimisation: Getting Cited by ChatGPT and Google
Search stopped being ten blue links. What it takes to be the source an AI answer cites, and how to tell if it is working.
Technical SEO Audit: What to Check, in What Order
Technical faults cost rankings quietly. This is the order that catches the costly ones first.