How to Build Schema in Next.js (Organization, Article, Product, FAQ)
Building schema in Next.js is straightforward in App Router with Server Components — render JSON-LD as part of the component tree. This guide walks the Next.js workflow. Pair with schema builder guide and headless debugging.
Step-by-step: How to build schema in Next.js
- Inventory schema types needed. Site-wide: Organization, WebSite. Per-page-type: Article (blog), Product (ecommerce), FAQPage (FAQ pages), BreadcrumbList (most pages). Plan before implementing.
- Install schema-dts for typing. npm install --save-dev schema-dts. Provides TypeScript types for all schema.org schemas. import type { Article, Product, Organization } from 'schema-dts'. Catches missing/wrong fields at compile time.
- Build schema helpers. src/lib/schema.ts: export function buildOrganization(): WithContext<Organization>; export function buildArticleSchema(article: ArticleData): WithContext<Article>; etc. Centralised, reusable, type-safe.
- Render in layout.tsx for site-wide. layout.tsx: import { buildOrganization, buildWebSite } from '@/lib/schema'. Render <script type='application/ld+json' dangerouslySetInnerHTML={{__html: JSON.stringify(buildOrganization())}} />. Two scripts — one Organization, one WebSite — or @graph combining.
- Render in page.tsx for page-specific. app/blog/[slug]/page.tsx: const article = await getArticle(slug); render <script type='application/ld+json' dangerouslySetInnerHTML={{__html: JSON.stringify(buildArticleSchema(article))}} />.
- Use @graph for multiple schemas. One JSON-LD block with @graph array containing all schemas. Cleaner than multiple <script> tags. { '@context': 'https://schema.org', '@graph': [organizationLD, articleLD, breadcrumbLD] }.
- Validate. Rich Results Test. Should show all expected schemas. Fix errors immediately. Add to staging deploys to prevent regressions reaching production.
Frequently Asked Questions
Why use schema-dts in Next.js?
TypeScript types for schema.org. Without it, schema objects are untyped JavaScript — typos and missing fields surface only at runtime via validator. With schema-dts, your IDE catches errors during development: required fields, wrong types, invalid @type values.
Should I use @graph or separate <script> tags?
@graph is preferred. Cleaner output, easier for Google to parse, single JSON object to validate. Use @graph at the top level with all your schemas in the array.
How do I add FAQPage schema to Next.js?
Component takes FAQ data (array of {question, answer}). Builds FAQPage JSON-LD with mainEntity array. Render in page that has FAQ content. Verify in Rich Results Test. Note: Google's FAQ snippet display narrowed in 2023 — schema still useful for AI agents and Bing.
Best Next.js schema libraries?
schema-dts (types only, no runtime). next-seo (Pages Router-focused but works in App Router — provides JSON-LD components for common schemas). Built-in Metadata API doesn't handle JSON-LD. Most projects: schema-dts + custom helpers, no other library needed.
Can I render schema from Server Components in App Router?
Yes — Server Components are the ideal place for schema. They render server-side, include the JSON-LD in initial HTML, no client JS needed. Don't render schema from Client Components ('use client') unless you have a specific reason — it ships unnecessary JS.