Structured data is one of those things every developer knows they should implement, but few actually do. Why? Because writing JSON-LD by hand is error-prone, tedious, and easy to get wrong.
What if you could generate type-safe structured data with autocomplete, validation, and zero runtime overhead?
The Problem with JSON-LD
Here’s what typical JSON-LD looks like:
{
"@context": "https://schema.org",
"@type": "Article",
"headline": "My Blog Post",
"author": {
"@type": "Person",
"name": "Jane Doe"
},
"datePublished": "2026-02-10"
}
Looks simple, right? But try maintaining this across dozens of pages:
- Did you forget the
@context? - Is
datePublishedin the right format? - Did you typo
ArticleasAticle? - Is this even valid according to schema.org?
These mistakes cost you search rankings and AI visibility.
## Enter Schema Sentry
Schema Sentry is a type-safe library for generating JSON-LD structured data. It gives you:
✅ Full TypeScript autocomplete – No more guessing field names
✅ Compile-time validation – Catch errors before they reach production
✅ Zero runtime overhead – Everything happens at build time
✅ Works with both Pages Router and App Router – Your choice of Next.js patterns
✅ CI/CD validation – Automated checks in your pipeline
## Quick Example
Instead of hand-writing JSON:
// ❌ Error-prone manual JSON
<script
type="application/ld+json"
dangerouslySetInnerHTML={{
__html: JSON.stringify({
"@context": "https://schema.org",
"@type": "Article",
"headline": "My Post",
// Did I get all required fields? Who knows!
})
}}
/>
Use type-safe builders:
import { Schema, Article } from "@schemasentry/next";
// ✅ Type-safe with autocomplete
const article = Article({
headline: "My Post",
authorName: "Jane Doe",
datePublished: "2026-02-10",
url: "https://example.com/blog/post",
});
export default function Page() {
return <Schema data={article} />;
}
Same output, zero guesswork.
Pages Router vs App Router
Good news: Schema Sentry works identically with both Next.js routing patterns.
App Router (Next.js 13+)
// app/blog/[slug]/page.tsx
import { Schema, Article, BreadcrumbList } from "@schemasentry/next";
export default function BlogPost({ params }: { params: { slug: string } }) {
const article = Article({
headline: "Getting Started",
authorName: "Jane Doe",
datePublished: "2026-02-10",
url: `https://example.com/blog/${params.slug}`,
});
const breadcrumbs = BreadcrumbList({
items: [
{ name: "Home", url: "https://example.com" },
{ name: "Blog", url: "https://example.com/blog" },
],
});
return (
<>
<Schema data={[article, breadcrumbs]} />
<article>{/* content */}</article>
</>
);
}
Pages Router (Classic Next.js)
// pages/blog/[slug].tsx
import Head from "next/head";
import { Schema, Article, BreadcrumbList } from "@schemasentry/next";
export default function BlogPost() {
const article = Article({
headline: "Getting Started",
authorName: "Jane Doe",
datePublished: "2026-02-10",
url: "https://example.com/blog/post",
});
const breadcrumbs = BreadcrumbList({
items: [
{ name: "Home", url: "https://example.com" },
{ name: "Blog", url: "https://example.com/blog" },
],
});
return (
<>
<Head>
<title>Getting Started - My Blog</title>
</Head>
<Schema data={[article, breadcrumbs]} />
<article>{/* content */}</article>
</>
);
}
The only difference? App Router doesn’t need next/head because it supports native metadata.
Supported Schema Types
Schema Sentry includes builders for the most common types:
- Organization – Company/publisher info
- WebSite – Site metadata
- Article / BlogPosting – Blog posts and articles
- Product – E-commerce products with offers
- FAQPage – FAQ sections with expandable questions
- HowTo – Step-by-step guides
- BreadcrumbList – Navigation breadcrumbs
-
Person – Author/contributor info
## CI/CD Validation
Here’s where it gets powerful. Schema Sentry includes a CLI for automated validation:
// schema-sentry.manifest.json
{
"routes": {
"/": ["Organization", "WebSite"],
"/blog": ["WebSite"],
"/blog/getting-started": ["Article"],
"/products/widget": ["Organization", "Product"],
"/faq": ["FAQPage", "Organization"]
}
}
Add to your GitHub Actions:
# .github/workflows/schema-check.yml
name: Schema Validation
on: [push, pull_request]
jobs:
validate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v2
- run: pnpm install
- run: pnpm build
- run: pnpm schemasentry validate
Now your CI will fail if:
- A page is missing expected schema
- Schema types don’t match the manifest
- Invalid JSON-LD is generated
Never ship broken structured data again.
## Why Structured Data Matters
### For Traditional SEO
Google uses JSON-LD to create rich snippets in search results: - Article headlines and publication dates
- Product prices and ratings
- FAQ dropdowns
- Breadcrumb navigation
These rich results get higher click-through rates than plain blue links.
### For AI Discovery
This is the big one that most developers are missing. AI systems like: - ChatGPT
- Claude
- Perplexity
- Google Bard
…all use structured data to understand and cite content. Without proper schema, your content is invisible to the AI discovery layer.
## Getting Started
# Install packages
npm install @schemasentry/next
npm install -D @schemasentry/cli
# Or with pnpm
pnpm add @schemasentry/next
pnpm add -D @schemasentry/cli
Create your first schema:
import { Schema, Organization } from "@schemasentry/next";
const org = Organization({
name: "My Company",
url: "https://example.com",
logo: "https://example.com/logo.png",
description: "We build amazing things",
});
export default function Home() {
return (
<>
<Schema data={org} />
<h1>Welcome</h1>
</>
);
}
That’s it! The <Schema /> component injects the JSON-LD into your page’s <head> automatically.
Live Examples
Check out the complete working examples:
- App Router Example – Modern Next.js 13+ patterns
-
Pages Router Example – Classic Next.js patterns
Both demonstrate the same UI with all 11+ schema types.
## Summary
Adding structured data doesn’t have to be painful: - Type safety catches errors at compile time
- Autocomplete guides you to the right fields
- CI validation prevents broken schema from shipping
- Zero runtime cost – everything is static
-
Works with any Next.js routing pattern
Your future self (and your search rankings) will thank you.
—
Have you implemented structured data on your Next.js site? What challenges did you face?
Schema Sentry is open source under MIT license. Star us on GitHub if you found this helpful!
