Structured data helps search engines understand your pages and can unlock rich results (FAQ, breadcrumbs, product snippets). In a headless setup, the best approach is to model structured data inputs in your CMS and render JSON-LD server-side.
This guide focuses on the practical schemas most CMS-driven sites need:
- Article
- FAQPage
- BreadcrumbList
- Product
Table of Contents
- How JSON-LD works (quickly)
- What to model in the CMS vs generate in code
- Article schema (blog posts)
- FAQ schema (FAQPage)
- Breadcrumb schema (BreadcrumbList)
- Product schema
- How to render JSON-LD in Next.js safely
- Validation checklist
How JSON-LD works (quickly)
JSON-LD is a <script type="application/ld+json"> block in your HTML. It doesn’t change what users see; it provides machine-readable meaning:
- what the page is (Article / Product / FAQ)
- who published it
- what the key entities are
You can include multiple JSON-LD blocks per page.
What to model in the CMS vs generate in code
Good rule:
- Model in CMS: content editors own it
- headline, description, author, FAQ Q/A, product name, offers, etc.
- Generate in code: derived from routing and site config
- canonical URL, breadcrumb URLs, publish organization, site logo URL
Avoid letting editors paste raw JSON-LD unless you truly need a “custom schema” escape hatch—otherwise you’ll fight invalid JSON and inconsistent structure.
Article schema (blog posts)
Use Article schema for blog posts and long-form content.
Model fields (typical):
title(headline)description(excerpt)slugpublishedAtupdatedAt(optional)coverImage(optional)authorName(or author reference)
Then generate JSON-LD with:
@type:Article(orBlogPosting)headlinedatePublisheddateModified(if you have it)image(if you have cover image)authorandpublisher
If you don’t have authors as content, a simple site-wide author works fine.
FAQ schema (FAQPage)
FAQ schema can produce rich results, but only if the FAQ content is actually visible on the page.
Model a FAQ section as structured fields:
items[]:questionanswer(plain text is safest; rich text is okay if you strip markup)
JSON-LD shape:
@type:FAQPagemainEntity: array ofQuestionobjects
Important: don’t add FAQ schema to pages without real FAQs; that’s considered spammy.
Breadcrumb schema (BreadcrumbList)
Breadcrumb schema is great for:
- blog categories
- docs hierarchies
- multi-level marketing pages
You usually generate it from routing + CMS metadata:
- Home → Blog → Category → Post
Model in CMS only what you can’t infer:
- category title/slug
- page title/slug
Then generate breadcrumb items as:
- position 1..n
- name
- item (absolute URL)
Product schema
Product schema is for e-commerce, pricing catalogs, and product landing pages where a product/offer is the page’s primary subject.
Model fields:
- product name
- description
- brand (optional)
- image(s)
- sku (optional)
- offers:
- price
- currency
- availability
- url
If you have multiple plans (pricing tiers), consider:
- Product page with multiple offers
- or separate “Plan” pages if each plan has its own landing page
How to render JSON-LD in Next.js safely
In Next.js, render JSON-LD server-side and inject it as a script tag.
Key safety rules:
- Build the JSON object in code (don’t concat strings).
- Use
JSON.stringify(schemaObject)and inject it in a script tag. - Avoid including user-generated HTML in schema fields.
If you have multiple schemas:
- one script per schema, or
- one
@graphwith multiple nodes
Validation checklist
Before shipping:
- Validate with Google’s Rich Results Test and Schema Markup Validator
- Make sure URLs are absolute and canonical
- Dates are ISO 8601
- Schema matches visible content
- No contradictory fields (e.g. availability vs price missing)
If you want to expand structured data next:
- Organization + Website
- Sitelinks search box (for big sites)
- HowTo schema (for step-by-step posts)