Headless CMS Schema Integration
Headless CMS stores content in APIs. Your front end (Next.js, Nuxt, Astro, etc.) maps API fields to Schema.org JSON-LD during static generation or server render.
Architecture options
Build-time (SSG)
Fetch CMS data at build time. Embed JSON-LD in each page's HTML output. Best for stable content and fast TTFB.
Request-time (SSR)
Fetch CMS data per request and inject JSON-LD in the response. Use when content changes frequently and cache invalidation is handled.
Webhooks + rebuild
CMS webhook triggers a rebuild or cache purge when editors publish. Keeps static sites fresh without per-request API calls.
Field mapping workflow
- Define the Schema.org type for each CMS content model (Article, Product, Event)
- List required properties for that type
- Map CMS fields to JSON-LD keys in your page component or layout
- Build sample output with the Schema Generator
- Implement a small builder function per content type
Example shape in TypeScript:
function buildArticleSchema(entry: CmsArticle) {
return {
'@context': 'https://schema.org',
'@type': 'Article',
headline: entry.title,
datePublished: entry.publishedAt,
author: { '@type': 'Person', name: entry.authorName },
};
}
Platform notes
| CMS | Typical fetch | Gotcha |
|---|---|---|
| Contentful | REST or GraphQL Delivery API | Locale-specific fields need explicit mapping |
| Strapi | REST content API | Custom components map to nested schema objects |
| Sanity | GROQ queries | Portable Text needs plain-text extraction for description |
| Ghost | Content API | Built-in meta; extend with custom JSON-LD in theme |
Performance
- Generate JSON-LD in the same data fetch as page content (one round trip)
- Avoid N+1 API calls per page
- Cache CMS responses at the edge when using SSR
Validation
- Test rendered HTML URLs, not raw API JSON
- Use Google Rich Results Test per template
- Monitor Google Search Console after deploy
See CMS Integrations for the shared checklist.
