Schema.org JSON-LD that AI agents actually use
Schema.org has thousands of types. Most are noise. In 2026, four types do real work for both Google rich results and AI agent ingestion. This guide is the practical short list, with the exact JSON-LD to ship.
The short list
| Type | When to use | Surfaces that read it |
|---|---|---|
| Organization | Once, in your root layout | Google Knowledge Panel, AI agents looking for entity identity |
| WebSite | Once, in your root layout | Google sitelinks search box |
| Article | Every blog post and long-form page | Google Top Stories, AI citations, Discover |
| BreadcrumbList | Every page deeper than the homepage | Google rich result, agent navigation context |
| FAQPage | Pages with a visible Q&A list | Some AI assistants quote acceptedAnswer text |
Note: Google announced FAQ rich results are being removed in mid-2026. The schema is still parsed by other surfaces, so it is not wasted, but do not expect SERP changes.
Organization (root layout)
The schema that defines who you are. Lives in the root layout so it appears on every page.
{
"@context": "https://schema.org",
"@type": "Organization",
"name": "Acme Inc",
"url": "https://acme.com",
"logo": "https://acme.com/logo.png",
"sameAs": [
"https://github.com/acme",
"https://x.com/acme",
"https://linkedin.com/company/acme"
]
}The sameAs array is critical. AI agents use it to confirm entity identity across platforms.
WebSite with site search
Tells search engines (and some agents) how to query your site.
{
"@context": "https://schema.org",
"@type": "WebSite",
"name": "Acme Inc",
"url": "https://acme.com",
"potentialAction": {
"@type": "SearchAction",
"target": {
"@type": "EntryPoint",
"urlTemplate": "https://acme.com/search?q={search_term_string}"
},
"query-input": "required name=search_term_string"
}
}Use the literal string {search_term_string} as the placeholder. Yes, the curly braces stay.
Article (per blog post)
For every long-form page. Required fields are aggressive: skip any of these and Google will not show a rich result.
{
"@context": "https://schema.org",
"@type": "Article",
"headline": "Your post title (under 110 chars)",
"description": "Same as the meta description.",
"datePublished": "2026-05-15",
"dateModified": "2026-05-15",
"author": {
"@type": "Person",
"name": "Jane Doe",
"url": "https://acme.com/team/jane"
},
"publisher": {
"@type": "Organization",
"name": "Acme Inc",
"logo": {
"@type": "ImageObject",
"url": "https://acme.com/logo.png"
}
},
"mainEntityOfPage": {
"@type": "WebPage",
"@id": "https://acme.com/blog/your-post"
},
"image": "https://acme.com/blog/your-post/cover.png",
"url": "https://acme.com/blog/your-post"
}A common mistake: passing author as just a string. Use the object form. Agents extract Person URLs from it for byline attribution.
BreadcrumbList (every inner page)
Cheap and surprisingly high-leverage. Many AI assistants use it to understand site hierarchy when summarizing.
{
"@context": "https://schema.org",
"@type": "BreadcrumbList",
"itemListElement": [
{
"@type": "ListItem",
"position": 1,
"name": "Home",
"item": "https://acme.com/"
},
{
"@type": "ListItem",
"position": 2,
"name": "Blog",
"item": "https://acme.com/blog"
},
{
"@type": "ListItem",
"position": 3,
"name": "Your post title",
"item": "https://acme.com/blog/your-post"
}
]
}Always include the current page as the last list item.
FAQPage (only when the page actually has a FAQ)
Rule: the questions and answers must be visible to a human visitor. Hidden FAQ-only schema is policy violation territory.
{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "What is robots.txt?",
"acceptedAnswer": {
"@type": "Answer",
"text": "robots.txt is a plain-text file..."
}
}
]
}Where to put the script tag
The tag goes in the <head> of the page it describes. Use one script per schema. In Next.js App Router, render it inside the page or layout component:
const data = {
/* your schema */
};
export default function Page() {
return (
<>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(data) }}
/>
{/* page content */}
</>
);
}Do not store JSON-LD as a string in metadata.openGraph or similar fields. It belongs in the rendered head.
Validation
Always validate before deploying:
- Google Rich Results Test: paste a deployed URL or a code snippet.
- Schema Markup Validator: deeper schema.org-specific checks.
- Structured Data Validator: in-browser, no signup, validates required fields per type.
What to skip
These types sound useful but rarely earn their weight in 2026:
WebPageon every page. Redundant withArticleand explicit URL fields.Personas a top-level schema. Embed it insideArticle.authorinstead.Servicefor SaaS products. Vendors are inconsistent about reading it;ProductplusOfferis more reliable.- Custom types prefixed with
https://schema.org/Xthat do not exist. Validators will silently drop them.
Build the schema
Use the JSON-LD Generator to produce any of the four types interactively. It outputs a clean script tag and links to the validators.
Why this matters
JSON-LD is the cheapest, highest-leverage agent-readiness signal you can ship. It is read by Google, Bing, and AI ingestion pipelines for a fraction of the work it takes to optimize a Core Web Vital. Add the four types above to every relevant page once and the gain compounds for years.