Structured data tells search engines what a page actually contains — an article, its author, its publish date — instead of leaving them to infer it from markup. In Google it is what makes a result eligible for rich treatment: the author line, the date, the breadcrumb trail. The format Google recommends is JSON-LD, placed inside a script tag in the page head.
What to Add
For a blog, three schema types cover most of the value:
BlogPostingon each articleBreadcrumbListon any nested pagePersonorOrganizationonce, for the site owner
The Article Payload
function articleJsonLd(post: Post) {
return {
'@context': 'https://schema.org',
'@type': 'BlogPosting',
headline: post.title,
description: post.excerpt,
datePublished: post.createdAt,
dateModified: post.updatedAt,
author: { '@type': 'Person', name: 'Your Name' },
mainEntityOfPage: https://example.com/blog/${post.slug},
};
}
Rendering It
In the Pages Router, render it inside next/head. Serialize with a helper that escapes any opening angle bracket in the JSON string, so a value containing markup cannot terminate the script tag early:
// escape "<" as its unicode form before injecting
const toSafeJson = (data: object) =>
JSON.stringify(data).replaceAll('<', String.fromCodePoint(0x5c) + 'u003c');
<Head>
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: toSafeJson(articleJsonLd(post)) }}
/>
</Head>
In the App Router, render the same script tag directly in the server component.
Verifying
- Rich Results Test — paste the URL, confirm the type is detected with no errors
- Search Console, Enhancements — which structured-data types Google found, and any warnings
Common Mistakes
- Dates not in ISO 8601 (
2026-08-24T11:35:00Z) - A
headlinelonger than 110 characters — Google truncates it - Structured data describing content that is not visible on the page — a policy violation
Conclusion
A few hundred bytes of JSON-LD per page is one of the highest-leverage SEO changes for a blog: cheap to add, easy to validate, and it directly affects how results are displayed.