Implement structured data that earns rich results
JSON-LD is the recommended format (Google's preference). Schema.org types are the vocabulary. Rich results in Google and citations in AI search engines are the outcomes.
High-value schema types (implement these first)
| Type |
Rich result earned |
Required fields |
Organization |
Knowledge panel, sitelinks search |
name, url, logo |
WebSite |
Sitelinks search box |
url, potentialAction (SearchAction) |
FAQPage |
FAQ dropdowns in SERP |
mainEntity → Question → acceptedAnswer |
Article |
Top stories, rich snippet |
headline, author, datePublished, image |
Product |
Product snippet with price/rating |
name, offers, aggregateRating |
HowTo |
How-to steps in SERP |
name, step array |
BreadcrumbList |
Breadcrumb in SERP URL |
itemListElement array |
LocalBusiness |
Local pack, knowledge panel |
name, address, telephone |
JSON-LD placement
Prefer <head> as a <script type="application/ld+json"> block. Google also supports JSON-LD placed in the <body> (including markup injected by JavaScript), so in-body placement is valid when <head> injection isn't practical — <head> is simply the cleaner default. One <script> block per schema type per page (or a @graph array for multiple types).
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "What is your refund policy?",
"acceptedAnswer": {
"@type": "Answer",
"text": "We offer a 30-day full refund, no questions asked."
}
}
]
}
</script>
Common mistakes that block rich results
- Content mismatch — schema claims a
price or rating that doesn't appear on the page. Google requires visible content to match.
- Missing required fields — check Google's required/recommended fields per type at developers.google.com/search/docs/appearance.
- Incorrect
datePublished format — must be ISO 8601 (2026-06-17T09:00:00+00:00).
- Markup on 404/noindex pages — Google won't process structured data on non-indexable pages.
- Multiple conflicting types — use
@graph array to combine without conflict.
Steps
- Audit existing markup. Paste page source into Google Rich Results Test; review Search Console → Enhancements for errors. Identify what's present, what's broken, what's missing.
- Prioritise by page type. Homepage → Organization + WebSite. Blog posts → Article. FAQs → FAQPage. Product pages → Product. All inner pages → BreadcrumbList.
- Implement in JSON-LD. Populate all required fields; add recommended fields for richer results. Confirm all schema claims match visible page content.
- Validate. Run through Google Rich Results Test (schema.googleapis.com/v1/richResults); fix any
errors (not just warnings).
- Monitor. After deployment, check Search Console → Enhancements in 48–72 hours for indexation of new schema.
- Record evidence. Screenshot Rich Results Test passing; note which enhancements are expected.
Review checklist
- JSON-LD in
<head> — not inline or in body.
- All required fields present — per Google's type documentation.
- Content matches page — every schema claim visible on the rendered page.
- Rich Results Test passes — zero errors (warnings acceptable).
- BreadcrumbList on all inner pages — not just the homepage.
- Search Console errors cleared — no existing structured data errors before adding new.
Rules
- Schema that describes content not visible on the page is spam — Google may penalise it.
- Fix Search Console errors on existing schema before adding new types.
- Never use Microdata or RDFa — JSON-LD only (maintainable and Google's preference).
1---2name: schema-markup3description: Use when implementing, auditing, or validating structured data (schema markup) on a website. Triggers on "structured data", "schema.org", "JSON-LD", "rich results", "rich snippets", "FAQ schema", "Product schema", "schema errors in Search Console", or "why no rich results". NOT for general SEO audits — use `seo-audit`. For AI-search citation optimisation, use `aeo`.4---56# Implement structured data that earns rich results78JSON-LD is the recommended format (Google's preference). Schema.org types are the vocabulary. Rich results in Google and citations in AI search engines are the outcomes.910## High-value schema types (implement these first)1112| Type | Rich result earned | Required fields |13|------|--------------------|----------------|14| `Organization` | Knowledge panel, sitelinks search | `name`, `url`, `logo` |15| `WebSite` | Sitelinks search box | `url`, `potentialAction` (SearchAction) |16| `FAQPage` | FAQ dropdowns in SERP | `mainEntity` → `Question` → `acceptedAnswer` |17| `Article` | Top stories, rich snippet | `headline`, `author`, `datePublished`, `image` |18| `Product` | Product snippet with price/rating | `name`, `offers`, `aggregateRating` |19| `HowTo` | How-to steps in SERP | `name`, `step` array |20| `BreadcrumbList` | Breadcrumb in SERP URL | `itemListElement` array |21| `LocalBusiness` | Local pack, knowledge panel | `name`, `address`, `telephone` |2223## JSON-LD placement2425Prefer `<head>` as a `<script type="application/ld+json">` block. Google also supports JSON-LD placed in the `<body>` (including markup injected by JavaScript), so in-body placement is valid when `<head>` injection isn't practical — `<head>` is simply the cleaner default. One `<script>` block per schema type per page (or a `@graph` array for multiple types).2627```html28<script type="application/ld+json">29{30 "@context": "https://schema.org",31 "@type": "FAQPage",32 "mainEntity": [33 {34 "@type": "Question",35 "name": "What is your refund policy?",36 "acceptedAnswer": {37 "@type": "Answer",38 "text": "We offer a 30-day full refund, no questions asked."39 }40 }41 ]42}43</script>44```4546## Common mistakes that block rich results4748- **Content mismatch** — schema claims a `price` or `rating` that doesn't appear on the page. Google requires visible content to match.49- **Missing required fields** — check Google's required/recommended fields per type at developers.google.com/search/docs/appearance.50- **Incorrect `datePublished` format** — must be ISO 8601 (`2026-06-17T09:00:00+00:00`).51- **Markup on 404/noindex pages** — Google won't process structured data on non-indexable pages.52- **Multiple conflicting types** — use `@graph` array to combine without conflict.5354## Steps55561. **Audit existing markup.** Paste page source into Google Rich Results Test; review Search Console → Enhancements for errors. Identify what's present, what's broken, what's missing.572. **Prioritise by page type.** Homepage → Organization + WebSite. Blog posts → Article. FAQs → FAQPage. Product pages → Product. All inner pages → BreadcrumbList.583. **Implement in JSON-LD.** Populate all required fields; add recommended fields for richer results. Confirm all schema claims match visible page content.594. **Validate.** Run through Google Rich Results Test (schema.googleapis.com/v1/richResults); fix any `errors` (not just `warnings`).605. **Monitor.** After deployment, check Search Console → Enhancements in 48–72 hours for indexation of new schema.616. **Record evidence.** Screenshot Rich Results Test passing; note which enhancements are expected.6263## Review checklist6465- **JSON-LD in `<head>`** — not inline or in body.66- **All required fields present** — per Google's type documentation.67- **Content matches page** — every schema claim visible on the rendered page.68- **Rich Results Test passes** — zero errors (warnings acceptable).69- **BreadcrumbList on all inner pages** — not just the homepage.70- **Search Console errors cleared** — no existing structured data errors before adding new.7172## Rules7374- Schema that describes content not visible on the page is spam — Google may penalise it.75- Fix Search Console errors on existing schema before adding new types.76- Never use Microdata or RDFa — JSON-LD only (maintainable and Google's preference).