Add Article Schema to Your Blog Posts
26 May 2026Schema markup doesn’t change how your post reads to a human. It changes how a search engine or an AI assistant parses what your post is — author, publish date, headline, all machine-readable instead of guessed from the HTML around them.
What it actually buys you
Without structured data, Google infers article metadata from your HTML heuristically — it usually gets the title right, sometimes gets the date wrong (picks up a “related posts” date instead), and rarely gets the author right at all. JSON-LD removes the guessing. It’s also increasingly how AI answer engines attribute a claim back to a source instead of just paraphrasing it with no citation.
The minimum viable Article schema
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "BlogPosting",
"headline": "Add Article Schema to Your Blog Posts",
"description": "JSON-LD that search engines and AI assistants actually read.",
"datePublished": "2026-05-26",
"dateModified": "2026-05-26",
"author": {
"@type": "Person",
"name": "Your Name",
"url": "https://yoursite.com/about/"
},
"publisher": {
"@type": "Organization",
"name": "Your Site Name",
"logo": {
"@type": "ImageObject",
"url": "https://yoursite.com/logo.png"
}
},
"mainEntityOfPage": {
"@type": "WebPage",
"@id": "https://yoursite.com/posts/schema-markup-for-articles/"
},
"image": "https://yoursite.com/images/og/schema-markup-for-articles.png"
}
</script>
Use BlogPosting for a blog, Article for more general editorial content, NewsArticle only if you’re actually a news publisher — Google does check this loosely against context.
Build it as a Hugo partial, not by hand per post
<!-- layouts/partials/article-schema.html -->
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "BlogPosting",
"headline": {{ .Title | jsonify }},
"description": {{ .Description | jsonify }},
"datePublished": {{ .Date.Format "2006-01-02" | jsonify }},
"dateModified": {{ .Lastmod.Format "2006-01-02" | jsonify }},
"author": { "@type": "Person", "name": {{ .Site.Params.author | jsonify }} },
"mainEntityOfPage": { "@type": "WebPage", "@id": {{ .Permalink | jsonify }} }
}
</script>
jsonify handles escaping — quotes or special characters in a title won’t break the JSON if you use it instead of raw string interpolation. Include this partial in your post layout once, and every post gets valid schema automatically, pulling from front matter you’re already writing.
Required fields Google actually checks
| Field | Required? | Common mistake |
|---|---|---|
headline |
Yes | Over 110 characters gets truncated in rich results |
datePublished |
Yes | Format must be ISO 8601, not "May 26, 2026" |
author |
Yes | A string instead of a Person/Organization object — fails validation |
image |
Recommended | Must meet minimum resolution (1200px wide is safe) |
publisher.logo |
Recommended for NewsArticle |
Often forgotten entirely |
Validate before you trust it
curl -s https://yoursite.com/posts/your-post/ | grep -A 30 'application/ld+json'
Then paste the output into Google’s Rich Results Test. It’ll flag missing required fields immediately — don’t guess, check every time you change the template, because a typo in the Go template syntax fails silently and just omits the whole script tag from the rendered page.
Once the partial is in place this costs you nothing per post. It’s pure upside: better rich results, more reliable attribution, and a machine-readable version of the metadata you’re already writing in front matter anyway.