Introduction
As developers, we spend countless hours optimising our applications for performance, accessibility, and user experience. Yet there’s one optimization that often gets overlooked: structured data. It’s the secret sauce that helps search engines and AI systems understand your content, but implementing it correctly has traditionally been painful.
In this article, we’ll explore how to add type-safe JSON-LD structured data to your Next.js applications using Schema Sentry—a library designed to make structured data generation as easy as writing TypeScript.
What is Structured Data and Why Should You Care?
Structured data is a standardised format (JSON-LD) that describes your page content to machines. Think of it as metadata that tells Google, Bing, ChatGPT, and other systems:
What your page is about
Who wrote it
When it was published
What product you’re selling
How to navigate your site
Real-World Impact
Without structured data, search engines guess. With it, they know. This leads to:
Rich search results - Articles with publication dates, products with prices, FAQs with expandable answers
Better AI visibility - ChatGPT, Claude, and Perplexity use structured data to cite and recommend content
Higher click-through rates - Rich snippets stand out in search results
The Traditional Approach (And Its Problems)
Here’s how most developers add structured data today:
<script
type="application/ld+json"
dangerouslySetInnerHTML={{
__html: JSON.stringify({
"@context": "https://schema.org",
"@type": "Article",
"headline": "My Blog Post",
"author": {
"@type": "Person",
"name": "Jane Doe"
},
"datePublished": "2026-02-10"
})
}}
/>
What’s Wrong With This?
No type safety - Typo in "@type": "Aticle"? Good luck finding it
No validation - Invalid schema? You’ll only know when Google rejects it
Maintenance nightmare - Change a field name? Update it everywhere manually
No autocomplete - IDE can’t help you remember schema.org field names
These aren’t just annoyances—they directly impact your SEO and AI discoverability.
Introducing Schema Sentry
Schema Sentry solves these problems by providing type-safe builders for JSON-LD structured data. It works with both Next.js App Router and Pages Router.
Installation
# Using npm
npm install @schemasentry/next
npm install -D @schemasentry/cli
# Using pnpm
pnpm add @schemasentry/next
pnpm add -D @schemasentry/cli
# Using yarn
yarn add @schemasentry/next
yarn add -D @schemasentry/cli
Basic Usage
Let’s start with a simple example—adding Article schema to a blog post:
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 with Next.js",
authorName: "Jane Doe",
datePublished: "2026-02-10",
dateModified: "2026-02-10",
url: `https://example.com/blog/${params.slug}`,
description: "Learn Next.js from scratch",
image: "https://example.com/images/nextjs.jpg"
});
const breadcrumbs = BreadcrumbList({
items: [
{ name: "Home", url: "https://example.com" },
{ name: "Blog", url: "https://example.com/blog" },
{ name: "Getting Started", url: `https://example.com/blog/${params.slug}` }
]
});
return (
<>
<Schema data={[article, breadcrumbs]} />
<article>
{/* Your content here */}
</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 with Next.js",
authorName: "Jane Doe",
datePublished: "2026-02-10",
url: "https://example.com/blog/post",
description: "Learn Next.js from scratch"
});
return (
<>
<Head>
<title>Getting Started - My Blog</title>
</Head>
<Schema data={article} />
<article>{/* content */}</article>
</>
);
}
Key difference: App Router doesn’t need next/head because it supports native metadata API.
Supported Schema Types
Schema Sentry includes builders for the most commonly used schema.org types:
1. Organization
Perfect for company information that appears on multiple pages:
import { Organization } from "@schemasentry/next";
const org = Organization({
name: "Acme Corporation",
url: "https://acme.com",
logo: "https://acme.com/logo.png",
description: "Building the future of web development",
sameAs: [
"https://twitter.com/acme",
"https://linkedin.com/company/acme",
"https://github.com/acme"
]
});
2. Product (E-commerce)
Essential for any e-commerce site:
import { Product } from "@schemasentry/next";
const product = {
...Product({
name: "Premium Widget",
description: "The ultimate productivity tool",
url: "https://acme.com/products/widget",
image: "https://acme.com/images/widget.jpg",
brandName: "Acme",
sku: "WIDGET-001"
}),
offers: {
"@type": "Offer",
price: "99.00",
priceCurrency: "USD",
availability: "https://schema.org/InStock"
},
aggregateRating: {
"@type": "AggregateRating",
ratingValue: "4.8",
reviewCount: "1247"
}
};
3. FAQPage
Great for help sections and documentation:
import { FAQPage } from "@schemasentry/next";
const faq = FAQPage({
questions: [
{
question: "What is Schema Sentry?",
answer: "A type-safe library for generating JSON-LD structured data."
},
{
question: "Does it work with Pages Router?",
answer: "Yes! It works with both App Router and Pages Router."
}
]
});
4. HowTo
Perfect for tutorials and step-by-step guides:

Join the conversation! Your thoughts help the community grow.