Article structured data
Search engines are getting smarter at understanding content, but they still need help from us. Article structured data is markup you add to your blog posts that tells Google, Bing, and other engines exactly what they're looking at—and gives them the context they need to rank and display your content properly. When you implement article structured data correctly, search engines understand your headline, publication date, author credentials, and featured image without guessing.
This matters more than many developers realize. A well-structured article can appear in Google News, get a richer snippet in search results, and signal freshness or authority to ranking algorithms. We're going to walk through the core fields you need, show you how to generate this markup from your CMS, and help you avoid the mistakes that make search engines ignore your hard work.
The headline field: precision over creativity
Your headline in article structured data should match the <h1> or primary title on the page. This is not the place to be vague or clever. Search engines use this field to understand the main topic, and inconsistencies between your page title, meta title, and structured data headline create confusion.
In a real scenario: you're running an engineering blog about WebSocket best practices. Your page headline is "Building Real-Time Features with WebSockets: A Production Guide". Your structured data headline should be identical or a very close variant—not shortened to "WebSockets 101" or expanded to include marketing language.
{
"@context": "https://schema.org",
"@type": "BlogPosting",
"headline": "Building Real-Time Features with WebSockets: A Production Guide"
}When you pull this from your CMS, map it directly to the field you use for the page's main title. If your CMS has separate fields for "Display Title" and "SEO Title", use the Display Title for structured data—that's what readers see and what makes sense to search engines.
Publication and modification dates: freshness signals
The datePublished and dateModified fields tell search engines when content was first published and when it was last updated. Google uses these dates to determine freshness, especially for news-related or time-sensitive content. If you update a post to fix errors or add new information, updating dateModified is a legitimate way to signal that the content is still current.
Here's where teams often go wrong: they update the modification date every time they fix a typo, which dilutes the signal. Reserve dateModified for meaningful updates—new sections, corrected technical information, or significant rewrites. A typo fix doesn't need to bump the date.
Use ISO 8601 format for both fields: YYYY-MM-DD or the full YYYY-MM-DDTHH:MM:SS+00:00 for timestamp precision.
{
"@context": "https://schema.org",
"@type": "BlogPosting",
"headline": "Output caching in .NET",
"datePublished": "2024-10-22",
"dateModified": "2025-01-15"
}Your CMS should store these as datetime fields. When you render the article, pull publishedAt and lastUpdatedAt directly into the structured data. If your CMS doesn't track modification dates separately, at minimum you need the publish date—that's non-negotiable for BlogPosting schema.
Author with profile URL: building credibility
Search engines and readers both want to know who wrote something. The author field in article structured data should include a name and, ideally, a URL to the author's profile or website. This builds credibility and helps search engines understand the expertise behind the content.
Think about a real scenario: you publish a deep technical article on Kafka partitioning. Including author markup with a link to the writer's profile page—which lists their other articles, their experience, and maybe their social presence—tells Google that this isn't anonymous content. That author credibility can influence how the piece ranks.
{
"@context": "https://schema.org",
"@type": "BlogPosting",
"headline": "Designing Kafka Topics for High-Throughput Systems",
"author": {
"@type": "Person",
"name": "Engineering Team",
"url": "https://expona.dev/team"
}
}In your CMS, store the author's name and a slug or URL to their profile page. When rendering the structured data, build the author object from those fields. If you don't have individual author pages, a team page or about page with author bios works too. The key is that the URL points to something real—not a generic homepage.
For organizations publishing under a team name rather than individual bylines, use "@type": "Organization" instead of "Person" and link to your main website or team page.
Image: visual signals and preview appearance
The image field tells search engines which visual represents your article. This image should be at least 1200 pixels wide (and ideally 1200x630 pixels for optimal aspect ratio). When your article appears in search results, news aggregators, or social shares, this is often the image that displays.
Imagine you've written a post about Docker networking. You include a clean, custom diagram showing network topology. That diagram—properly sized and relevant—should be your article image in structured data. It improves click-through rates in search results because users see a preview of what they're getting.
{
"@context": "https://schema.org",
"@type": "BlogPosting",
"headline": "Docker Networking for Microservices",
"image": {
"@type": "ImageObject",
"url": "https://expona.dev/images/docker-networking-diagram.png",
"width": 1200,
"height": 630
}
}In your CMS, store the featured image as a required field for each article. When generating structured data, pull the image URL and dimensions. If your CMS doesn't store dimensions, you can calculate them server-side or store them as metadata. Don't guess the dimensions—include accurate width and height values.
The image URL must be a full absolute URL (including protocol and domain), not a relative path. Search engines need to be able to fetch the image independently.
Generating from your CMS fields: practical implementation
The real work happens when you connect these schema fields to your CMS data. Most content management systems have the basic fields you need: title, publish date, author, and featured image. The challenge is mapping them correctly and ensuring quality data goes in.
Here's a real example using a typical backend setup. You have a Blog model with these fields:
| Field Name | Type | Maps To |
|---|---|---|
| title | String | headline |
| publishedAt | DateTime | datePublished |
| updatedAt | DateTime | dateModified |
| authorName | String | author.name |
| authorUrl | String | author.url |
| featuredImageUrl | String | image.url |
| featuredImageWidth | Integer | image.width |
| featuredImageHeight | Integer | image.height |
In a Node.js/Next.js setup, you might generate this in a helper function:
function generateArticleSchema(article) {
return {
"@context": "https://schema.org",
"@type": "BlogPosting",
"headline": article.title,
"datePublished": article.publishedAt.toISOString().split('T')[0],
"dateModified": article.updatedAt.toISOString().split('T')[0],
"author": {
"@type": "Person",
"name": article.authorName,
"url": article.authorUrl
},
"image": {
"@type": "ImageObject",
"url": article.featuredImageUrl,
"width": article.featuredImageWidth,
"height": article.featuredImageHeight
},
"publisher": {
"@type": "Organization",
"name": "Expona",
"url": "https://expona.dev"
}
};
}
// In your page/component:
const schema = generateArticleSchema(article);
// Render as JSON-LD in the <head>:
<script
type="application/ld+json"
dangerouslySetInnerHTML={{ __html: JSON.stringify(schema) }}
/>The key principle: pull data directly from your CMS fields, validate that none are missing or empty, and render the JSON-LD in a <script type="application/ld+json"> tag in your page <head>. Don't manually craft schema markup for each article—automate it from your CMS.
Common mistakes
Mismatched or generic headlines: Using a different headline in structured data than on the page confuses search engines. Keep them consistent. Avoid generic titles like "Blog Post" or "New Article".
Incorrect date formats: Use ISO 8601 (YYYY-MM-DD). Don't use localized formats, timestamps with milliseconds, or inconsistent formatting across articles.
Missing author URLs: Including just an author name is weak. Search engines want to know where to find more about the author. Always include a valid profile URL.
Images too small or wrong aspect ratio: An image under 1200 pixels wide doesn't meet schema requirements. A square image won't display well in previews. Test with Google's Rich Results Test to verify dimensions.
Using relative image paths: Structured data needs absolute URLs. Never use /images/my-image.png—use the full https://expona.dev/images/my-image.png.
Not validating with tools: Generate your schema, then paste it into Google's Rich Results Test or Schema.org Validator. Many issues only surface in testing.
Over-updating dateModified: Bumping the modified date every time you deploy code or fix formatting dilutes the freshness signal. Reserve it for genuine content updates.
Key takeaways
- Article structured data helps search engines understand your blog posts and display them better in results and aggregators.
- The essential fields are headline, datePublished, dateModified, author (with URL), image (1200px+ wide), and publisher organization.
- Map these fields directly from your CMS—don't manually craft schema for each article.
- Use ISO 8601 date format, absolute image URLs, and validate with Google's Rich Results Test.
- Keep headlines consistent between the page and structured data to avoid confusion.
- Include author profile URLs to build credibility; a bare name is less useful to search engines.
- Update dateModified only for meaningful content changes, not for minor formatting fixes.
- Render schema as JSON-LD in the
<head>using a<script type="application/ld+json">tag.






Comments
Loading comments…