Content Accessibility
Schema.org JSON-LD
Structured semantic markup for web content via JSON-LD, enabling search engines and AI agents to understand it.
What is Schema.org JSON-LD?
Schema.org JSON-LD is machine-readable metadata embedded in a page as a <script type="application/ld+json"> block. Schema.org is a shared vocabulary of data types from Google, Microsoft, Yahoo, and Yandex. JSON-LD is the syntax for expressing that data.
Example JSON-LD on a homepage:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "SoftwareApplication",
"name": "Agent Ready Scanner",
"applicationCategory": "DeveloperApplication",
"url": "https://agentsready.io",
"description": "Free AI-readiness scanner for websites"
}
</script>
The markup is embedded in <head> or <body> and has no visual effect — it is only visible to search engines and AI agents.
Why does a site need Schema.org JSON-LD?
Schema.org solves a fundamental problem: HTML contains content but doesn’t say what it means. Is a paragraph of text a review? A schedule? An instruction? Without markup, AI has to guess. With markup, it knows exactly.
AI assistants (ChatGPT, Perplexity, Google AI Overview) use structured data when generating answers. A page with FAQPage is cited as a ready-made answer — this is the primary tool of AEO. A page with Product and aggregateRating gets rich snippets.
For AI agents:
An agent extracts data from markup faster and more accurately than from raw HTML.
Practical effects:
FAQPage→ “Question and answer” rich snippet, citation in AI answers- Recipe/article → rich snippet with image
Organization→ Knowledge PanelSoftwareApplication→ rating in app search results
How to implement Schema.org JSON-LD?
Minimal set for most sites:
<!-- Homepage: WebSite -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "WebSite",
"name": "Site Name",
"url": "https://example.com"
}
</script>
<!-- About page: Organization -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Organization",
"name": "Company",
"url": "https://example.com",
"logo": "https://example.com/logo.png",
"contactPoint": {
"@type": "ContactPoint",
"email": "hello@example.com"
}
}
</script>
FAQ page:
{
"@context": "https://schema.org",
"@type": "FAQPage",
"mainEntity": [
{
"@type": "Question",
"name": "What is agent-readiness?",
"acceptedAnswer": {
"@type": "Answer",
"text": "Agent-readiness is the degree to which a site..."
}
}
]
}
Priority types for agent-readiness:
| Type | When to use |
|---|---|
WebSite | Homepage |
Organization | About page |
SoftwareApplication | Homepage for SaaS / apps |
FAQPage | FAQ page |
Article / TechArticle | Articles, documentation |
DefinedTerm | Glossary pages |
Service | Services / pricing page |
For Astro (our approach):
---
const schema = {
'@context': 'https://schema.org',
'@type': 'SoftwareApplication',
name: 'Agent Ready Scanner',
url: 'https://agentsready.io',
};
---
<script type="application/ld+json" set:html={JSON.stringify(schema)}></script>
Validation: before deploying, check at validator.schema.org — there should be 0 errors, ideally 0 warnings.
How do we check Schema.org?
Our scanner performs GET / (the homepage) and verifies:
- Presence of JSON-LD blocks — find all
<script type="application/ld+json">in the HTML - Valid JSON — each block parses without errors
@typefrom the priority list —Organization,Product,SoftwareApplication,Article,FAQPage,BreadcrumbList,WebSite- Required fields per type — for each type, check for required fields (e.g.,
WebSiterequiresnameandurl)
Status pass — at least one block is valid and contains a priority type with the required fields. Status fail — no JSON-LD block found or all blocks are invalid. Status neutral — other markup formats found (Microdata, RDFa) but not JSON-LD.