Product schema is structured data on your product pages that states the verifiable facts about what you sell: the name, the price, the currency, whether it is in stock, which variants exist. AI engines read it because a model cannot verify what is not structured. Without it, an engine scrapes a price out of your page layout and guesses. With it, the engine reads a price you declared. Every crawler in our robots.txt reference parses this same markup, and it is the single highest-leverage page change a brand can make for AI search.
What the markup actually is
Product schema is a block of JSON-LD, a small script you add to a product page, written in a shared vocabulary maintained at schema.org. It does not change what shoppers see. It sits in the page code and tells machines what the page is about. Google, Bing, and the AI crawlers all parse the same schema.org types, so one block serves every engine.
The block goes on each product page as a script tag. Put it in the head or the body, either works. What matters is that it is in the initial HTML, the code the server sends before any JavaScript runs. Most AI crawlers do not execute JavaScript, so markup injected by client-side scripts is invisible to them. If your site renders product content with JavaScript, read our guide on whether AI crawlers can see JavaScript websites first, because that problem has to be fixed before this markup can do its job.
The minimum Google requires
Schema.org itself requires nothing; it is a vocabulary, not a rulebook. The requirements come from the consumers. Google's product structured data docs set the bar: a Product needs a name, plus at least one of offers, review, or aggregateRating, or the markup is ignored. Inside an Offer, price is required, and priceCurrency is required for merchant listings and strongly recommended everywhere else. Always include it. A price without a currency is a number, not a fact.
Everything below is the full working set: the required core plus the recommended properties that make the markup actually useful to an AI engine answering a buying question.
The complete Product block
Here is a full JSON-LD block for a single product with one offer. In the example, [yourdomain.com] is a placeholder, replacing yourdomain.com with your actual domain. Every field maps to a schema.org Product or Offer property.
<script type="application/ld+json">
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Trailhead GTX Hiking Boot",
"image": [
"https://[yourdomain.com]/images/trailhead-gtx-1.jpg"
],
"description": "Waterproof hiking boot with a Vibram outsole and full-grain leather upper.",
"sku": "TH-GTX-08",
"brand": {
"@type": "Brand",
"name": "Trailhead Supply Co."
},
"offers": {
"@type": "Offer",
"url": "https://[yourdomain.com]/products/trailhead-gtx-hiking-boot",
"price": "189.00",
"priceCurrency": "USD",
"availability": "https://schema.org/InStock",
"itemCondition": "https://schema.org/NewCondition"
},
"aggregateRating": {
"@type": "AggregateRating",
"ratingValue": "4.6",
"reviewCount": "212"
}
}
</script>
Field by field:
- name: the product name exactly as shoppers see it. Keep it identical to the page headline. Engines cross-check the markup against the visible page.
- image: at least one product image URL. Use the full URL, not a relative path.
- description: one or two sentences from the actual product description. Do not write a separate marketing version for the markup.
- sku: your internal SKU. This is what lets an engine match your product across your site, your feed, and reseller pages.
- brand: typed as Brand with a name. This is the entity link that tells engines which brand the product belongs to. See the Organization section below for the full linkage.
- offers.price / priceCurrency: the current selling price and its three-letter currency code. If the price changes, this block has to change with it. Stale markup is worse than none.
- offers.url: the canonical URL of the product page the offer belongs to.
- offers.availability: one of schema.org's fixed values, such as InStock, OutOfStock, PreOrder, or LimitedAvailability. Use the full https://schema.org/ URL form. This is the field AI engines lean on most when answering "is it available."
- offers.itemCondition: NewCondition, UsedCondition, or RefurbishedCondition. Include it; engines use it to filter.
- aggregateRating: the average rating and the count of reviews, but only if those reviews actually appear on this page. See the reviews section.
Variants: one product, many sizes and colors
A product that comes in sizes or colors needs more than one Offer. Schema.org provides a ProductGroup type for exactly this, with each variant linked through hasVariant. The group holds the shared facts (name, brand, description); each variant is its own Product with its own Offer carrying that variant's price and availability.
{
"@context": "https://schema.org",
"@type": "ProductGroup",
"name": "Trailhead GTX Hiking Boot",
"brand": { "@type": "Brand", "name": "Trailhead Supply Co." },
"hasVariant": [
{
"@type": "Product",
"name": "Trailhead GTX Hiking Boot, Size 9",
"sku": "TH-GTX-08-09",
"offers": {
"@type": "Offer",
"url": "https://[yourdomain.com]/products/trailhead-gtx-hiking-boot?size=9",
"price": "189.00",
"priceCurrency": "USD",
"availability": "https://schema.org/InStock"
}
},
{
"@type": "Product",
"name": "Trailhead GTX Hiking Boot, Size 10",
"sku": "TH-GTX-08-10",
"offers": {
"@type": "Offer",
"url": "https://[yourdomain.com]/products/trailhead-gtx-hiking-boot?size=10",
"price": "189.00",
"priceCurrency": "USD",
"availability": "https://schema.org/OutOfStock"
}
}
]
}
Do not use AggregateOffer for variants. Google's docs say this explicitly: AggregateOffer describes one product sold by multiple sellers (with lowPrice and offerCount), not one product in multiple variants. Marking variants as an aggregate offer merges their prices into a range and throws away per-variant availability, which is exactly the fact an AI engine needs when someone asks for size 10.
Reviews and aggregateRating
Include review markup only for reviews that are visible on the page. An aggregateRating with a reviewCount of 212 needs 212 reviews a shopper can actually read. A single Review block needs an author with a real name. Google's guidelines treat markup for reviews that do not exist on the page as spam, and a manual action means the structured data on the page gets ignored entirely. AI engines apply the same logic more quietly: a rating they cannot verify is a rating they will not cite.
If you have no reviews, leave these fields out. The markup is still valid with offers alone.
Brand and Organization linkage
The brand property connects the product to your brand as an entity, not just a text string. Type it as Brand or Organization and give it a name that matches everywhere else: your site header, your social profiles, your business listings. When the name in your markup matches the name in your llms.txt file and the name on your pages, engines resolve all three to one entity instead of three candidates. For the full treatment of brand consistency, see our llms.txt guide. If your company publishes Organization markup on the homepage, keep the brand name identical in both places.
Validate before you ship
Two free tools, no signup:
- Google's Rich Results Test: paste a product URL and it shows exactly which product fields Google detects, with errors and warnings per field.
- The Schema Markup Validator: checks the JSON-LD against the schema.org vocabulary itself, which catches typos in property names that Google's tool may not flag.
Run both on a handful of product pages, including at least one variant page and one out-of-stock product. The out-of-stock check matters: your availability values have to change when inventory does, and the validator will not tell you the value is stale.
Common mistakes
The markup price does not match the visible page. This is the most common failure and the most damaging. If the JSON-LD says $189 and the page shows $209, Google ignores the markup, and an AI engine that catches the mismatch trusts neither number. Generate the markup from the same data that renders the page, never from a separate feed.
Duplicate conflicting markup. Most commonly: the theme emits one Product block and a reviews app or SEO app emits a second one, with different prices. Crawlers see two competing sets of facts and pick one at random or drop both. Audit the page source for every script tag of type application/ld+json before adding your own.
Fake or imported reviews. Marking up reviews that are not on the page, or copying review counts from a marketplace listing, is structured data spam. Leave the fields out until the reviews are real and visible.
Markup on the wrong pages. Product markup belongs on product pages. Putting Offer blocks on category pages, blog posts, or the homepage creates facts with no page behind them.
Markup injected by JavaScript. If the JSON-LD only appears after your scripts run, Google may eventually see it and every other AI crawler will not. It has to be in the server-rendered HTML.
Adding it on your platform
The markup is the same everywhere. Where you put it depends on your platform. One rule before you start: check whether your site already emits product markup. View a product page's source and search for application/ld+json. If something is already there, fix that block: fill in its missing fields and correct its values rather than adding a second block that conflicts with it. Review and SEO apps are the usual source of duplicates, so check what is installed before you touch anything.
See the platform guides:
- How to add product schema on Shopify
- How to add product schema on WooCommerce
- How to add product schema on BigCommerce
- How to add product schema on Salesforce Commerce Cloud
- How to add product schema on Adobe Commerce
- How to add product schema on Wix
- How to add product schema on Squarespace
- How to add product schema on a self-hosted site
- How to add product schema on a custom website
What this guide does not cover
This guide covers the markup. It does not cover getting crawlers to your pages in the first place (that is the robots.txt reference), getting them past your edge security (see our guide on robots.txt saying allow while crawlers stay blocked), or keeping prices and availability accurate as inventory changes, which is monitoring work. And markup makes you recommendable, not purchasable: letting the agent complete the checkout is the transaction layer, a separate job.
Frequently Asked Questions
Which product schema fields are most critical for AI search engines?
Should I use JSON-LD or Microdata for AI search markup?
Can duplicate product schema blocks confuse AI crawlers?
Check your own brand now
Run the free scan. It takes seconds, no signup, and shows whether AI crawlers can read your product pages today: aizii.ai/aeo-scan
Run the free scan