Blog SEO with JSON-LD Structured Data
Meta tags and structured data will not save a thin post, but they do help search engines and social apps understand what a page is. For blogs, the usual win is clean titles/descriptions plus Article (or BlogPosting) JSON-LD that matches visible content. This is a practical setup guide, not a promise of rich-result magic.
Meta tags that earn the click
| Tag | Practice |
|---|---|
title | ~50–60 characters; primary topic near the front |
meta description | ~120–160 characters; concrete outcome, not keyword soup |
canonical | Absolute URL of the preferred copy |
og:title / og:description / og:image | Match or thoughtfully adapt the page; real 1200×630-ish image |
twitter:card | summary_large_image when you have art |
Write descriptions like a human subtitle. Duplicate titles across posts dilute branding and confuse SERPs.
JSON-LD Article skeleton
Google documents preference for JSON-LD in a script tag. Minimal shape:
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "BlogPosting",
"headline": "Blog SEO with JSON-LD Structured Data",
"description": "Practical Article JSON-LD for blogs...",
"image": ["https://example.com/og/seo-structured-data.png"],
"datePublished": "2025-03-01T00:00:00+09:00",
"dateModified": "2026-07-16T00:00:00+09:00",
"author": {
"@type": "Person",
"name": "Your Name",
"url": "https://example.com/about"
},
"publisher": {
"@type": "Organization",
"name": "Your Site",
"logo": {
"@type": "ImageObject",
"url": "https://example.com/logo.png"
}
},
"mainEntityOfPage": {
"@type": "WebPage",
"@id": "https://example.com/en/blog/seo-structured-data/"
}
}
</script>
Keep headline aligned with the visible <h1>. Mismatches look manipulative and help no one.
Dates, authors, and updates
Use ISO 8601 with timezone offset or Z. Update dateModified when you meaningfully change content — not on every typo deploy if that would mislead readers. Multi-author blogs should model the real byline; fake authors for “E-E-A-T theater” backfire.
FAQ and Breadcrumb extras
If the page truly has an FAQ section, FAQPage schema can be appropriate. Do not dump invisible FAQs solely for stars. BreadcrumbList helps understanding site hierarchy on articles nested under /blog/....
Only mark up content users can see. Hidden schema is a policy risk.
Implementation tips for Astro/Next
- Generate JSON-LD from the same frontmatter that drives the page title
- Absolute URLs only — relative paths in
imageare common breakage - One primary Article object per post page; avoid contradictory duplicates from theme + plugin
- Escape
</script>inside JSON if you ever inline user text (preferJSON.stringify)
const jsonLd = {
"@context": "https://schema.org",
"@type": "BlogPosting",
headline: post.data.title,
datePublished: post.data.pubDate.toISOString(),
// ...
};
Validation workflow
- Deploy a preview.
- Run Google Rich Results Test on the URL.
- Fix errors (missing fields, invalid images).
- Spot-check Facebook/Slack debuggers for OG tags (cache may lag).
- Monitor Search Console enhancements for ongoing issues.
What structured data will not do
- Rank a hollow 200-word post above strong competitors
- Replace inbound links or clear information architecture
- Guarantee rich results — eligibility ≠ entitlement
Prioritize helpful content and clean HTML first; schema is documentation for machines.
Launch checklist
- Unique title + description
- Canonical set
- OG image resolves (200 OK, adequate size)
- JSON-LD validates
- Visible author/date consistent with schema
- Noindex only when intentional (previews, thin duplicates)
Bottom line
Treat SEO metadata and JSON-LD as a contract with crawlers and social scrapers: accurate titles, real dates, real authors, absolute image URLs. Set the template once in your site framework, validate on a sample of posts, and invest remaining energy in articles people actually want to read.