Quick Answer: Product schema for ecommerce is JSON-LD markup that describes each product's name, image, description, sku, brand, offer, and ratings so Google can show price, availability, and stars directly in search results. Pages selling the product qualify for merchant listings; pages only describing it qualify for product snippets.

Here is the part most guides get backwards: the hard work of product schema is not writing the JSON. The syntax takes twenty minutes. The hard work is satisfying Google's eligibility rules, because a technically valid block that violates one of them earns nothing, silently, forever. This page gives you a complete worked example you can adapt, then walks through the eligibility layer where product markup actually succeeds or fails. This is Vector 6 in our methodology, Structure: markup a machine can trust without reading between the lines.

What the markup does that a product page alone cannot

Product schema converts the facts a shopper reads on your page into fields a crawler can extract without interpretation. Google's own Product structured data documentation lists the payoff plainly: price, availability, ratings, shipping cost, and return windows displayed in the result itself, plus eligibility for the Shopping tab, Popular Products, and product results in Google Images.

That display advantage compounds in a way plain blue links do not. A result showing a 4.7 rating, an in-stock badge, and a price answers three purchase questions before the click. Your competitor's unmarked result answers none. Click-through moves accordingly, and in a category where every store carries similar inventory, the result that resolves doubt first tends to take the sale.

There is a second audience now. AI shopping surfaces, from Google's AI Overviews to assistant-driven product recommendations, assemble answers from sources they can parse with confidence. Structured product data is the lowest-friction way to be one of those sources. We treat product markup as dual-purpose: rich results today, machine legibility for whatever recommendation surface arrives next.

Merchant listing vs product snippet: one type, two doors

Google splits Product markup into two experiences, and choosing wrong wastes the effort. The dividing question is simple: can a shopper buy the product on this page?

An online store wants merchant listings on every product page. A blog reviewing gear wants product snippets. A store that also publishes buying guides wants both, on different templates. Mixing them up, say by putting offer-free snippet markup on a purchasable page, forfeits the stronger treatment.

The properties that decide eligibility

Strip away the optional fields and the skeleton is short. For a merchant listing, Google requires name and an offers block containing price (or a price specification) and expects priceCurrency. For a product snippet, you need name plus at least one of review, aggregateRating, or offers. Everything else is recommended, but "recommended" undersells it: the recommended fields are what separate a minimal listing from one that wins the richer placements.

The fields worth treating as mandatory in practice:

A complete worked example you can adapt

The block below describes a queen duvet cover sold by Maple & Loom, an invented Ontario linen shop that exists only for this example. Swap the values for your own and it is deployable. It is valid JSON-LD as written.

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "Product",
  "name": "Harbourline Linen Duvet Cover, Queen, Sage",
  "image": [
    "https://www.mapleandloom.example/img/harbourline-duvet-1x1.jpg",
    "https://www.mapleandloom.example/img/harbourline-duvet-4x3.jpg",
    "https://www.mapleandloom.example/img/harbourline-duvet-16x9.jpg"
  ],
  "description": "Stonewashed 100% European flax linen duvet cover in queen size, with interior corner ties and a hidden button closure. Pre-washed for softness; colour is garment-dyed sage.",
  "sku": "ML-DUV-Q-SAGE",
  "brand": {
    "@type": "Brand",
    "name": "Maple & Loom"
  },
  "offers": {
    "@type": "Offer",
    "url": "https://www.mapleandloom.example/products/harbourline-linen-duvet-cover",
    "priceCurrency": "CAD",
    "price": 249.00,
    "priceValidUntil": "2026-12-31",
    "availability": "https://schema.org/InStock",
    "itemCondition": "https://schema.org/NewCondition"
  },
  "aggregateRating": {
    "@type": "AggregateRating",
    "ratingValue": 4.7,
    "reviewCount": 38
  }
}
</script>

Three details in that block deserve attention because they are where real implementations drift. The image array carries three aspect ratios, which Google's documentation asks for on merchant listings. The priceCurrency is explicit; a bare price with no currency is ambiguous to a parser and Canadian stores get mispriced as USD without it. And availability uses the full schema.org URL form, not the shorthand string, which some validators tolerate and some surfaces do not.

If you are new to placing JSON-LD on a page at all, our walkthrough on how to add schema markup covers the mechanics for every platform. The example above drops into the same <script type="application/ld+json"> pattern described there.

aggregateRating and the review rules that trip stores up

Review markup carries the strictest policy layer in the product ecosystem, mostly because it was the most abused. The rule set that matters, drawn from Google's review snippet documentation and its 2019 self-serving reviews change:

The full policy detail, including how review markup behaves outside ecommerce, is in our companion piece on review schema markup.

"The pattern I keep finding in ecommerce audits is a store with three schema apps installed and all three emitting a Product block, each slightly different. Google sees a page that states three prices for one item and quietly trusts none of them. Removing two apps has fixed more merchant listings for us than adding markup ever has."

Matt Griffin, Founder, Formative Digital

Shopify: what the theme emits and where it stops

Most Shopify themes, including current Online Store 2.0 themes, emit a baseline Product block automatically: name, price, availability, URL. That baseline is why Shopify stores often show partial rich results with zero effort. It is also why store owners assume the job is done when it is roughly a third done.

The recurring Shopify gaps: the brand field mapped to the vendor value, which is frequently the store's own name rather than the product's brand; a single image instead of the multi-ratio array; sku omitted or mapped inconsistently across variants; and review data missing entirely unless a review app injects it. When a review app does inject it, you get the duplicate-block problem, two Product objects on one page disagreeing about the same item.

The clean fix is one source of truth: audit what the theme outputs with the Rich Results Test, then either extend the theme's JSON-LD in the layout or suppress it and ship one complete block from a single app or snippet. Shopify's own Liquid variables expose sku, barcode, and vendor per variant, so a developer can build the full example above natively without an app subscription.

WooCommerce: more control, more ways to misfire

WooCommerce outputs Product schema through its core plus whatever SEO plugin is active, and the flexibility cuts both ways. Yoast, Rank Math, and Woo's native output can each claim the job; sites running two of them at once ship the same duplicate-block conflict Shopify apps cause. Pick one emitter and disable the rest.

Watch the price field on variable products. Some configurations emit the lowest variant price while the visible page shows a range, and a mismatch between markup price and displayed price is a documented eligibility failure. For variable products the safer pattern is AggregateOffer with lowPrice and highPrice, or per-variant markup where the platform supports it. Also confirm the currency: multicurrency plugins have a habit of hard-coding the store default into the JSON-LD while the shopper sees a converted figure.

Common disqualifiers: why valid markup earns nothing

These are the failures we see most in the wild, all of them invisible to a syntax validator:

Retail is where we have pressure-tested this discipline most heavily. Our engagement with Mattress Miracle, a Brantford retail client, paired structured data coverage with a large content program and grew the domain to 82,400 monthly organic visits by the SEMrush April 2026 snapshot. Structured data was one instrument in that result, not the whole orchestra, and results of that size depend on industry, competition, and the site's starting condition. But the schema layer is what let the product and content pages be read by machines at full fidelity, and none of it would have counted with the disqualifiers above in play. The full write-up is in the Mattress Miracle case study.

Validating, monitoring, and what good looks like

Two tools, used in sequence. The Rich Results Test checks a single URL and tells you which experience the page is eligible for, merchant listing or product snippet, and which recommended fields are absent. Search Console's Merchant listings report then watches the whole catalogue over time, surfacing errors per URL as they appear. New products, theme updates, and app changes all introduce regressions; the report is where you catch them before they compound.

A healthy catalogue reads like this in practice: every product URL eligible for merchant listings, zero errors, warnings limited to fields you genuinely cannot supply, and the schema regenerated server-side from the same database that renders the visible page so drift is structurally impossible. That last clause is the design principle worth stealing whatever your platform.

Where product markup fits in the wider schema graph

Product blocks do not float alone. The stores that read most coherently to machines connect them into a graph: Organization markup identifying the merchant, BreadcrumbList markup mapping the catalogue hierarchy, and, for stores with physical locations, LocalBusiness markup tying the web catalogue to the storefront entity. A shop in Hamilton selling online and in person needs both halves; our local business schema guide covers the storefront side of that pairing.

In Matt's experience with Ontario retailers, the graph question is where do-it-yourself implementations plateau: individual blocks validate, but nothing links them, so the machine sees fragments instead of a business. If you would rather hand the whole layer to a team that builds these graphs daily, that is our schema markup service, and our research library documents the methods behind it in the open.

Find out what machines see when they read your catalogue

Send us your store URL and we will map which product pages qualify for merchant listings, which are silently disqualified, and why, at no charge, with a reply inside one business day. The findings are yours to act on with any team you choose.

Product schema questions store owners actually ask

Do I need product schema if my Shopify theme already outputs some?

You need to check what it outputs, because most themes cover name, price, and availability and stop there. Brand, sku, full image arrays, and aggregateRating are usually missing. Run one product URL through the Rich Results Test, note the gaps, and fill them with a single corrected JSON-LD block rather than stacking multiple schema apps.

What is the difference between a merchant listing and a product snippet?

A merchant listing applies to pages where a shopper can buy the product directly, and it can surface in the Shopping tab, Popular Products, and image results. A product snippet applies to pages about a product you do not sell, such as reviews or comparisons, and shows stars, price, and availability in ordinary results. Same Product type, different eligibility.

Can I mark up ratings collected by my own review widget?

For products, yes. Google's self-serving review restriction applies to LocalBusiness and Organization types, where a business publishes ratings about itself. Ratings of individual products on the store that sells them remain eligible, provided the reviews are genuine, visible on the page, and not filtered to hide negative scores.

Why do my products show no rich results even though the schema validates?

Validation checks syntax, not eligibility. The usual culprits are markup on category pages instead of individual product pages, prices in the JSON-LD that disagree with the visible page, variant markup describing a range of products in one block, or a site quality level where Google declines the enhancement. Check Search Console's Merchant listings report for the specific complaint.

Does product schema matter for AI search tools like ChatGPT and Perplexity?

Yes, and increasingly so. Assistants that recommend products need machine-readable price, availability, and rating data to compare options with confidence, and structured data is the cleanest source of it. A product page an AI engine can parse without guessing is more likely to be named when a shopper asks for recommendations.

Questions about a specific catalogue, platform, or a Merchant listings report full of errors you cannot decode? Talk to us and bring the URL.