DeepSmith

Jul 26 · AEO & AI Visibility

14 min read

Article Schema for AI Search: How to Mark Up Blog Posts for Citation Eligibility

Avinash Saurabh
Avinash Saurabh · CO-Founder & CEO
Monochrome illustration of a blog post document card beside a JSON-LD code fragment, with headline, author, date and publisher metadata rows wired by thin lines out to AI engine nodes, under the cover line "Mark Up Posts for AI Citation".

You've heard that schema helps AI engines find you, and you've probably been putting it off because it looks like a developer job. It isn't. This guide walks you through adding complete Article or BlogPosting markup to your blog posts, the kind of article schema AI engines and Google both read natively, so your posts get recognized correctly and become eligible to be cited.

By the end you'll know which type to pick, which fields to fill, where to paste the block, and how to check your work. Blog post schema is one of the few AEO jobs with a clear finish line, which is exactly why it's worth doing first. Take it one step at a time. You're closer than you think.

Step 1: Get honest about what schema can and cannot do

Let's start here, because the wrong expectation is what makes people quit halfway.

Adding markup to a page means telling machines, in a vocabulary they read natively: this is an article, here's the title, here's who wrote it, here's when we published it, here's when we last updated it, here's the cover image, here's the organization behind it. That's the recognition layer.

What it buys you is eligibility. Google's own documentation is direct about this: Article structured data enables features like better title text, images, and dates in search results. It does not guarantee they show up. The algorithm still decides.

What about AI citations? Here's the honest picture, and I'd rather you hear it from me than find out later.

Pages cited by AI engines are roughly three times more likely to have JSON-LD than pages that aren't. That's a correlation drawn from analyzing six million URLs. It's why schema has a reputation as a signal of well-built sites.

Causation is a different story. One study tracked 1,885 pages that added JSON-LD over roughly seven months, matched each against three control pages that never added it, and compared citation changes 30 days before and after. Google AI Overviews moved slightly down relative to controls. Google AI Mode and ChatGPT moved slightly up, both statistically indistinguishable from zero. The researchers' own verdict: they can't tell whether the schema did a tiny bit of good or nothing at all.

So why bother? Because schema isn't a citation injector. It's the recognition and eligibility layer that makes everything else you do legible. Your authority, your freshness, your actual content quality: those are what earn the citation. Schema is what makes sure the machine knows whose article it's looking at, who wrote it, and when.

One more thing to file away. A figure circulates in blog posts claiming structured data cuts AI citation drop-off by 44%. No primary study is ever disclosed with it. Treat it as illustrative, not confirmed.

How you know this step is done: you can explain to your boss why you're adding schema without promising a citation lift.

Step 2: Pick the right @type for your post

Three types are eligible for the same Article rich result. Picking is easier than it looks.

TypeUse it for
ArticleGeneric articles, when neither subtype fits
NewsArticleActual journalism and time-sensitive reporting
BlogPostingBlog posts, the default for marketing content

Google's advice is to use the most specific applicable type. If the page is a blog post, use BlogPosting, not bare Article. You're in good company: BlogPosting is used by somewhere between one million and ten million domains, the same usage band as Article.

NewsArticle deserves a warning. It exists for real journalism and carries journalism-specific properties like dateline and printSection. Do not reach for it because your post feels newsy. Google has stated that marking non-news content as NewsArticle is a misuse policy violation.

Common mistake: using Article and BlogPosting together on the same page. Pick one type per page and move on.

How you know this step is done: you can say your type out loud in one word.

Step 3: Map the fields that actually get read

Good news first. Google's documentation says there are no required properties for Article structured data. Nothing here can break your page. The more recommended properties you provide, the higher the quality of the result.

Here's your working list. Fill these in and you're covered:

  1. headline: the article title, kept concise.
  2. image: your cover image, ideally in several aspect ratios.
  3. datePublished: when it first went live, ISO 8601 with a timezone offset.
  4. dateModified: when you last materially updated it.
  5. author: an array, holding a Person or an Organization.
  6. publisher: the Organization that publishes the content.

Then add these. They're not on Google's recommended list for the rich-result feature, but they materially help AI engines and other parsers understand the page, so include them anyway:

  1. description: a short summary, genuinely useful for AI summarization.
  2. url: the canonical URL.
  3. mainEntityOfPage: the canonical page identifier.
  4. inLanguage: a code like "en".

That's it. Ten fields. You can fill them in a lunch break.

This is also where a production pipeline earns its keep. Hand-mapping CMS fields to schema properties on every single post is the kind of repetitive work that quietly gets skipped when you're behind. DeepSmith's Content Studio produces publish-ready articles with the metadata already mapped, so the fields your schema needs are populated at creation instead of patched in afterward. Your CMS still renders the markup. The point is that nobody's hand-typing datePublished forty times a month.

How you know this step is done: every field above has a real value, and none say "TBD."

Step 4: Get author and publisher right

These two trip up more people than everything else combined. They're also the fields that carry the most meaning for a machine trying to work out whether you're a real source.

Author rules

List every author shown on the page. If your byline says two people co-wrote it, both go in the array. Not one.

Give each author a stable URL through author.url, or author.sameAs as a fallback. Point it at their profile page on your site, their personal site, or an about-me page. Google can disambiguate using either one. Supplying both is fine.

Use Person for named individuals. Use Organization when there's no byline at all, like a corporate blog that publishes under the company name.

Pro tip: the property is author, not authors. That single typo silently breaks the block, and it's the most common one there is.

Two more traps. Never write "author": "Jane Doe" as a plain string. It has to be an object, or an array of objects. And never point author.url at the article you're marking up. It points to a page about the author, not the page they wrote.

Publisher rules

publisher is the organization doing the publishing. It's a different thing from author, even when both are your company.

Your minimum viable block needs four things: @type of Organization, name, url, and a logo as an ImageObject with url, width, and height.

Two notes worth heeding. Absence of publisher often blocks Article rich-result eligibility, so don't treat it as optional. And your logo URL has to be crawlable and indexable. Keep it clear, well lit, at a sensible resolution, on a stable URL. Anyone quoting you an exact pixel minimum is guessing.

How you know this step is done: every author name on the page appears in the array, each with a URL that resolves to a page about them.

Step 5: Set up images that qualify

Your image property has real rules, and they're specific.

Supply multiple aspect ratios where you can: 16x9, 4x3, and 1x1. Google's own reference example uses exactly that triple. A single ratio still works, it just limits Google's options on surfaces that prefer a different shape.

The pixel floor is 50,000 pixels when you multiply width by height. Roughly 313x160 or larger.

Then the practical stuff:

  • URLs must be crawlable. Verify them, don't assume.
  • JPG, PNG, WebP, and GIF are safe formats.
  • No logos, no captions. Use a real content image.
  • Keep URLs stable. Nothing that rotates, like a stock photo of the day.
  • Use absolute URLs starting with https://. Never relative paths.

Common mistake: image URLs that 404 or get blocked by a CDN that doesn't like bots. Your image looks fine in a browser and is invisible to the crawler. Check it rather than trusting it.

How you know this step is done: you've loaded each image URL in a private window and it rendered.

Step 6: Write the block and put it in your template

Here's your complete starting point: a full article schema JSON-LD block with every field from Step 3 already in place. Copy it, swap the values, and you're most of the way there.

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "BlogPosting",
  "headline": "Article Schema for AI Search: How to Mark Up Blog Posts",
  "description": "A how-to guide explaining how to add Article and BlogPosting schema so AI engines can recognize and cite your posts.",
  "image": [
    "https://example.com/photos/16x9/cover.jpg",
    "https://example.com/photos/4x3/cover.jpg",
    "https://example.com/photos/1x1/cover.jpg"
  ],
  "datePublished": "2026-07-15T09:00:00+00:00",
  "dateModified": "2026-07-15T09:00:00+00:00",
  "author": [{
    "@type": "Person",
    "name": "Jane Doe",
    "url": "https://example.com/team/jane-doe",
    "sameAs": [
      "https://www.linkedin.com/in/janedoe",
      "https://janedoe.com"
    ]
  }],
  "publisher": {
    "@type": "Organization",
    "name": "Example Co.",
    "url": "https://example.com",
    "logo": {
      "@type": "ImageObject",
      "url": "https://example.com/logo.png",
      "width": 600,
      "height": 60
    }
  },
  "mainEntityOfPage": {
    "@type": "WebPage",
    "@id": "https://example.com/blog/article-schema-ai"
  },
  "url": "https://example.com/blog/article-schema-ai",
  "inLanguage": "en",
  "keywords": "article schema AI, blog post schema, JSON-LD"
}
</script>

Swap "@type" to Article if the page isn't a blog post, or NewsArticle only if you're genuinely publishing journalism.

Placement: drop the block in the <head> of your blog post template. Google's examples use <head>, and <body> also works, because JSON-LD is content-typed and never rendered on screen. Keep it to one block per page unless a sibling type like BreadcrumbList warrants a second.

The rule that matters more than placement: the script has to appear in the raw HTML response, not only after JavaScript runs. Schema injected by JavaScript that a crawler never executes is schema that doesn't exist. Use static HTML or server-side rendering. Then confirm it by viewing source and finding the block with your own eyes.

Your platform, briefly:

  • WordPress: plugins like Rank Math, Yoast with its structured data add-on, or Schema Pro will auto-detect your post type and emit the markup. Validate anyway. Theme-level JSON-LD can collide with plugin-level JSON-LD, so check your source for duplicate blocks.
  • Ghost: no built-in Article schema. Inject it site-wide through Code Injection with a Handlebars template that pulls title, primary author, dates, and feature image from post context. Validate every template that renders a post.
  • Webflow: no native support either. Use a custom code embed in the post template's <head>, or a third-party schema app, and bind the values to your CMS fields.
  • Next.js and other React frameworks: put the script in the server-rendered HTML stream so crawlers see it without executing JavaScript. Client-rendered JSON-LD that waits on hydration gets missed. A typed schema builder like schema-dts keeps your property names honest.

How you know this step is done: you hit Ctrl+U on the live post and your article schema JSON-LD is sitting right there in the source.

Step 7: Validate in the right order

Three tools, three jobs. Running them in the right sequence saves you a lot of circling.

  1. Schema Markup Validator (validator.schema.org). Start here, on the snippet itself, before it's live. It checks against the official schema.org vocabulary and catches pure syntax problems. It isn't Google-aware, so passing here doesn't promise you a rich result.
  2. Google Rich Results Test (search.google.com/test/rich-results). Run this on the live URL. It tells you whether Google can generate an Article rich result from your markup. It only covers Google-supported features, and it reports eligibility, never guaranteed display.
  3. Search Console URL Inspection. Last, after a recrawl, on a verified property. This is the only one showing how Google actually sees your page rather than simulating it. It's how you confirm the markup was genuinely ingested.

Syntax, then Google's view, then reality. That order.

This step stays yours, by the way. A pipeline can hand you correct metadata, but validation is still validation. Nothing replaces looking at what Google says it found.

How you know this step is done: URL Inspection reports your structured data on the live URL after a recrawl.

Step 8: Keep your dates honest

You're nearly finished, and this is the step people ship and then forget.

dateModified earns its place only if you actually maintain it. Update it when you materially revise the post, not when you fix a typo. Both dates need ISO 8601 with a timezone offset. "July 15, 2026" is invalid. "2026-07-15T09:00:00+00:00" is what a machine reads.

The rule that breaks builds: datePublished must be earlier than or equal to dateModified. Some validators treat a modified date that predates publication as a hard error. It happens more than you'd guess, usually through a migration or a backdated import.

Three more to watch as your blog grows:

  • A trailing comma anywhere in the block breaks JSON parsing entirely. The whole thing, gone, from one character.
  • If your headline drifts from the visible H1, that's a policy violation. Structured data has to represent what the reader actually sees.
  • On a paginated series, only the canonical page or the view-all page should carry story-level markup. Put the same block on every paginated page and engines read duplicates.

Then finish the loop: submit your sitemap, request indexing for new posts, and request a recrawl after you edit. Markup Google hasn't refetched is markup Google hasn't seen.

How you know this step is done: your dates validate, and a recrawl is requested.

What to do next

Don't retrofit your whole archive this week. Pick one post, ideally one that already earns traffic, and take it through all eight steps. One post start to finish teaches you more than eight half-finished ones.

Once the template's right, every future post inherits it for free. That's the real win here. You're fixing a template once, not a hundred articles. Blog post schema is template work, and template work compounds quietly while you get on with something else.

From there, look at the pieces schema can't do for you: the author authority behind the byline, the freshness of what you publish, whether your content answers the question someone actually asked. Schema for blog citations is the recognition layer. What gets you cited is being worth citing.

If the bottleneck is that you can't produce enough well-structured content to make any of this matter, that's a different problem, and it's the one DeepSmith exists to solve. You can start a free trial and see real drafts with metadata already wired in before you pay anything.

One post. This week. You've got this.

Frequently asked questions

Do I need both Article and BlogPosting schema on my blog posts?

No. Pick one type per page. For a blog post, use `BlogPosting`, since Google asks for the most specific applicable type. Using both on one page is a common error worth avoiding, and it's the fastest way to make otherwise clean schema for blog citations read as contradictory to a parser.

Will adding Article structured data get my pages cited by AI engines?

Not on its own. Pages that get cited are about three times more likely to have JSON-LD, but a controlled study of 1,885 pages adding schema found citation movement that was statistically indistinguishable from zero on ChatGPT and Google AI Mode. Schema makes your page recognizable and eligible. Content quality and authority earn the citation.

Where should the JSON-LD block go, in `<head>` or `<body>`?

Either works, because JSON-LD is content-typed and never rendered. Google's examples use `<head>`. What matters far more is that the block appears in the raw HTML response rather than being injected by JavaScript after load.

What are the required properties for Article schema?

There are none. Google's documentation states no properties are required. Fill in the recommended ones anyway: `headline`, `image`, `datePublished`, `dateModified`, `author`, and `publisher`. The more you provide, the better the result quality.