Google documentation entry point
Official rich result documentation: https://developers.google.com/search/docs/appearance/structured-data/article
Use for editorial pages where the visible content is a complete article with a clear byline, visible headline, primary image, and publication timestamps.
Key implementation documentation highlights
- Required properties for this implementation: headline, image, datePublished, dateModified, author.
- Recommended properties to improve robustness: publisher, mainEntityOfPage, description.
- Google typically expects content parity: schema values must match what users can see on-page.
- Use the Rich Results Test and URL Inspection to validate rendering, eligibility, and crawlability.
- Monitor the related enhancement report in Search Console after deployment for errors and warnings.
Article schema decision gates
Before emitting Article schema, the page should pass a few content and indexability checks. These gates prevent a reusable framework from marking up thin, utility, category, or non-indexable URLs as articles.
- Emit Article only when the page has a visible article body, a visible headline, a byline or author source, and publication metadata.
- Suppress Article schema when the URL is noindex, blocked from crawling, canonicalized to another page, or missing a stable canonical URL.
- Require a crawlable primary image before including image, and prefer the same image that appears in the article template or Open Graph metadata.
- Normalize dates to ISO 8601 and keep dateModified equal to or later than datePublished.
- Use headline for the Article title field. name can be included as a secondary field, but headline is the Article-specific property Google calls out.
Article subtype selection logic
A production framework should choose the most specific eligible type instead of defaulting every editorial URL to Article. The type decision should be deterministic and based on the page template, content purpose, and publisher rules.
- Use NewsArticle for timely reporting, announcements, and newsroom-style content where freshness and publication chronology matter.
- Use BlogPosting for opinion, analysis, tutorials, and blog-style resources that live in a blog or insights section.
- Use Article as the fallback when the page is editorial but does not cleanly match a narrower subtype.
- Avoid Article markup on landing pages, service pages, tag pages, author archives, faceted URLs, and thin excerpts.
Data sourcing model
Strong Article schema usually fails because fields are sourced from inconsistent places. Treat schema generation as a small data pipeline rather than a static snippet.
- Headline should come from the canonical H1 or editorial title field.
- Description should come from the visible dek, summary, or meta description only when it accurately summarizes the article.
- Author should come from the byline data model, not a hardcoded brand fallback unless the visible byline is the organization.
- Dates should come from publication and modified timestamps in the CMS, then be formatted consistently during build or render.
- Image should come from the primary article image or Open Graph image, after checking that the asset is crawlable and stable.
Template approach
Input (JavaScript)
const pageData = {
title: "Sample Article Entity",
description: "Primary on-page summary for Article content.",
url: "https://www.example.com/article/sample",
publishDate: "2026-01-20",
image: "https://www.example.com/assets/article.jpg",
authorName: "Example Author"
};
const staticTemplate = {
"@context": "https://schema.org",
"@type": "Article",
"headline": pageData.title,
"description": pageData.description,
"url": pageData.url,
"datePublished": pageData.publishDate,
"image": pageData.image,
"author": { "@type": "Person", "name": pageData.authorName }
};
Output (JSON)
{
"@context": "https://schema.org",
"@type": "Article",
"headline": "Sample Article Entity",
"description": "Primary on-page summary for Article content.",
"url": "https://www.example.com/article/sample",
"datePublished": "2026-01-20",
"image": "https://www.example.com/assets/article.jpg",
"author": {
"@type": "Person",
"name": "Example Author"
}
}
Conditional-logic framework
Input (JavaScript)
function chooseArticleType(source) {
if (source.isNewsroomContent) return "NewsArticle";
if (source.isBlogContent) return "BlogPosting";
return "Article";
}
function hasRequiredArticleFields(source) {
return Boolean(
source.title &&
source.url &&
source.publishDate &&
source.modifiedDate &&
source.image &&
source.authorName
);
}
function buildArticleSchema(source) {
if (!source.isIndexable || !hasRequiredArticleFields(source)) {
return null;
}
const schema = {
"@context": "https://schema.org",
"@type": chooseArticleType(source),
"headline": source.title,
"url": source.url,
"mainEntityOfPage": source.url,
"datePublished": source.publishDate,
"dateModified": source.modifiedDate,
"image": source.image,
"author": { "@type": "Person", "name": source.authorName }
};
if (source.description) schema.description = source.description;
if (source.publisherName) {
schema.publisher = { "@type": "Organization", "name": source.publisherName };
}
return schema;
}
Input (Python)
def chooseArticleType(source):
if source.get("isNewsroomContent"):
return "NewsArticle"
if source.get("isBlogContent"):
return "BlogPosting"
return "Article"
def hasRequiredArticleFields(source):
return bool(
source["title"] and
source["url"] and
source["publishDate"] and
source["modifiedDate"] and
source["image"] and
source["authorName"]
)
def buildArticleSchema(source):
if not source.get("isIndexable") or not hasRequiredArticleFields(source):
return None
schema = {
"@context": "https://schema.org",
"@type": chooseArticleType(source),
"headline": source["title"],
"url": source["url"],
"mainEntityOfPage": source["url"],
"datePublished": source["publishDate"],
"dateModified": source["modifiedDate"],
"image": source["image"],
"author": { "@type": "Person", "name": source["authorName"] }
}
if source.get("description"):
schema["description"] = source["description"]
if source.get("publisherName"):
schema["publisher"] = { "@type": "Organization", "name": source["publisherName"] }
return schema
Output (JSON)
{
"@context": "https://schema.org",
"@type": "BlogPosting",
"headline": "Sample Article Entity",
"url": "https://www.example.com/article/sample",
"mainEntityOfPage": "https://www.example.com/article/sample",
"datePublished": "2026-01-20",
"dateModified": "2026-02-03",
"image": "https://www.example.com/assets/article.jpg",
"author": {
"@type": "Person",
"name": "Example Author"
},
"description": "Primary on-page summary for Article content.",
"publisher": {
"@type": "Organization",
"name": "Example Publisher"
}
}
Why conditional logic is better than static templates
- Prevents emitting empty, null, or stale fields that frequently trigger rich result warnings.
- Supports multiple page states (for example: no author yet, no image yet, draft article, canonicalized syndicated article) without duplicate templates.
- Lets engineering teams centralize schema policy checks and validation in reusable code paths.
- Makes large-scale schema maintenance safer when content models evolve over time.
Common failure modes to monitor
- Article schema emits on a URL that is canonicalized elsewhere.
- dateModified is older than datePublished after a CMS migration or timezone conversion.
- The author value in schema does not match the visible byline.
- The image URL is blocked, redirected, missing dimensions, or replaced by a temporary CDN URL.
- The build process updates the HTML page but leaves the downloadable Markdown or documentation version stale.
Deployment checklist
- Compare every schema value against visible page content before release.
- Validate the final rendered HTML, not only the source template, because client-side rendering and build steps can change the emitted JSON-LD.
- Log suppressed Article schema cases so teams can distinguish intentional non-emission from generation failures.
- Re-run validation when article templates, author models, image handling, canonical logic, or publication-date fields change.
- Track error and warning counts by article subtype so NewsArticle, BlogPosting, and generic Article issues can be diagnosed separately.
Schema.org types and properties cited by Google for this rich result