Back to Blog

Product Schema Markup: What Google Actually Reads

·, Founder·Ecommerce SEO
product schema markupstructured datajson-ldmerchant listingsecommerce seo

Product schema markup is structured data, usually JSON-LD built from schema.org's Product and Offer types, that tells Google what a page sells: the product's name, image, price, availability, identifiers and reviews. Google reads it for two kinds of search results, product snippets and merchant listings, and each has its own required properties (Google Search Central).

Everything else in this guide follows from that split. Once you know which experience a page qualifies for, you know which fields matter.

Key takeaways

  • Google reads product schema markup for two kinds of results, product snippets and merchant listings, and each has its own required properties, per Google Search Central.
  • Google's merchant listings require a name, an image and an offer with a price above zero and a currency, per Google Search Central.
  • For products with sizes or colors, Google asks for the ProductGroup class with variesBy, hasVariant and productGroupID, plus Product markup for each variant, per Google Search Central.
  • A structured data manual action removes a page's eligibility for rich results but does not affect how it ranks in Google web search, per Google Search Central.

Product snippets vs merchant listings

Google describes product snippets as being "for product pages where people can't directly purchase the product," and merchant listings as being for "pages where customers can purchase products from you" (Google Search Central).

The requirements differ. Product snippets need a name and "either review or aggregateRating or offers," and only "editorial product review pages are eligible for the pros and cons appearance" (Google Search Central). Merchant listings need a name, an image and an offers object with a price and currency, and "unlike product snippets, merchant listing experiences require a price greater than zero" (Google Search Central).

Product snippetsMerchant listings
Typical pageReview sites, editorial roundups, product pages with no checkoutStore product pages with a cart
Requiredname, plus review, aggregateRating or offersname, image, offers with price and currency
PriceOffer is optionalPrice must be greater than zero
ExtrasPros and cons, on editorial review pages onlyShipping, returns, sizing and other shopping details

Google states that "only pages where a shopper can purchase a product are eligible for merchant listing experiences," and that these experiences include "the shopping knowledge panel, Google Images, popular product results, and product snippets" (Google Search Central). For a store, merchant listings are the target.

The format Google prefers

Google supports JSON-LD, Microdata and RDFa, and says it "recommends using JSON-LD for structured data if your site's setup allows it" (Google Search Central). JSON-LD sits in its own script block, separate from your visible HTML, which makes it easier to generate from product data and to audit.

Here is an illustrative example for a single product with no variants. The store, product, identifiers and price are invented:

{
  "@context": "https://schema.org",
  "@type": "Product",
  "name": "Washed Linen Shirt, Regular Fit",
  "image": [
    "https://example.com/images/linen-shirt-square.jpg",
    "https://example.com/images/linen-shirt-wide.jpg"
  ],
  "description": "A regular-fit shirt in washed linen with a button-down collar.",
  "sku": "LS-REG-NAVY-M",
  "brand": { "@type": "Brand", "name": "Example Clothing" },
  "offers": {
    "@type": "Offer",
    "url": "https://example.com/products/washed-linen-shirt",
    "price": "68.00",
    "priceCurrency": "USD",
    "availability": "https://schema.org/InStock",
    "itemCondition": "https://schema.org/NewCondition"
  }
}

It goes inside a <script type="application/ld+json"> element on the product page. The schema.org definitions for Product and Offer list every available property; Google's product documentation names the ones it reads for these results.

Required first, then recommended

For merchant listings, the required set is short: name, image, and an Offer with price (or priceSpecification.price) and priceCurrency "in three-letter ISO 4217 format" (Google Search Central). Google's general rule is "You must include all the required properties for an object to be eligible," and it advises you to "supply fewer but complete and accurate recommended properties" rather than many sloppy ones (Google Search Central).

These recommended properties, all listed in Google's merchant listing documentation, are the ones worth prioritizing for a store:

PropertyGoes onWhat it tells Google
gtin (or another GTIN property)ProductThe exact product, across sellers
brand.nameProductThe manufacturer or label
sku, mpnProductYour identifier and the manufacturer's
color, size, material, patternProductShopping attributes for apparel and similar goods
aggregateRating, reviewProductRatings and reviews, if they meet the review guidelines
availabilityOfferIn stock, out of stock, preorder
itemConditionOfferNew, used or refurbished
shippingDetailsOfferShipping cost and delivery time
hasMerchantReturnPolicyOfferReturn window and conditions
priceValidUntilOfferWhen a sale price ends

Be careful with priceValidUntil. Google warns that "your listing may not display if the priceValidUntil property indicates a past date" (Google Search Central). If you set it for a sale, update or remove it when the sale ends.

Shipping and returns belong at the store level

Google recommends defining return and shipping policies once, under your Organization markup, and using offer-level versions only to override them or when there is no standard policy (Google Search Central).

If you also use Google Merchant Center, the two sources meet: "Some experiences combine data from structured data and Google Merchant Center feeds if both are available" (Google Search Central). For shipping and returns, Google's order of precedence puts product-level feeds submitted in Merchant Center first (Google Search Central). Keep the feed and the markup consistent so one doesn't contradict the other.

Variants: ProductGroup, not a pile of Products

When a product comes in sizes or colors, Google asks you to "use the ProductGroup class with associated properties variesBy, hasVariant, and productGroupID," with Product markup for each variant (Google Search Central). On schema.org, ProductGroup is a subtype of Product that "represents a group of Products that vary only in certain well-described ways" (schema.org).

Google's variant documentation sets a few rules. "Each variant must have a unique ID in its corresponding structured data markup," such as a sku or gtin. variesBy should reference full schema.org URLs, and the supported values are color, size, suggestedAge, suggestedGender, material and pattern (Google Search Central).

URLs matter as much as markup. "The site must have the ability to preselect each variant directly with a distinct URL (using URL query parameters)," and preselecting includes "showing the right image, price, and availability." When all variants share one page, "there must be only one distinct canonical URL for the overall ProductGroup," usually the base URL with no variant selected (Google Search Central).

An illustrative, trimmed example with one variant shown (values invented):

{
  "@context": "https://schema.org",
  "@type": "ProductGroup",
  "name": "Washed Linen Shirt",
  "productGroupID": "LS-REG",
  "variesBy": ["https://schema.org/size", "https://schema.org/color"],
  "hasVariant": [
    {
      "@type": "Product",
      "sku": "LS-REG-NAVY-M",
      "name": "Washed Linen Shirt, Navy, M",
      "size": "M",
      "color": "Navy",
      "image": "https://example.com/images/linen-shirt-navy.jpg",
      "offers": {
        "@type": "Offer",
        "url": "https://example.com/products/washed-linen-shirt?color=navy&size=m",
        "price": "68.00",
        "priceCurrency": "USD",
        "availability": "https://schema.org/InStock"
      }
    }
  ]
}

On Shopify, themes "automatically include schema markup for products" (Shopify Help Center), and Shopify's structured_data Liquid filter outputs a schema.org Product for products with no variants and a ProductGroup for products that have them (Shopify developer docs). Check what your theme already outputs before adding an app that writes a second block.

Reviews and ratings

aggregateRating and review come with their own rules. Google's review snippet guidelines say "ratings must be sourced directly from users," that the review content you mark up must be "readily available to users from the marked-up page," and "Don't aggregate reviews or ratings from other websites" (Google Search Central).

The same guidelines restrict self-serving reviews on pages that use LocalBusiness or other Organization markup, where the business controls the reviews about itself. That rule names those types, not Product (Google Search Central).

What gets your markup ignored

Markup has to match the page. Google's policies say "your structured data must be a true representation of the page content" and "don't mark up content that is not visible to readers of the page" (Google Search Central). Mismatches that turn up on stores include a price in the markup that differs from the displayed price, InStock on a sold-out item, and ratings in JSON-LD with no reviews on the page.

The penalty is to rich results, not rankings. Per the same policies, a structured data manual action "means that a page loses eligibility for appearance as a rich result," and "it doesn't affect how the page ranks in Google web search." Valid markup is no promise either: "Google does not guarantee that your structured data will show up in search results" (Google Search Central).

How to test

Google recommends checking structured data "using the Rich Results Test during development" and using the rich result status reports in Search Console after deployment (Google Search Central). Product pages have two reports: Merchant listings, "for pages where shoppers can buy products," and Product snippets, for other product pages such as reviews and aggregator sites (Google Search Central).

The Rich Results Test catches syntax errors and missing required fields. It won't catch everything; Google notes that some problems are "not a syntax issue, and so the Rich Results Test won't be able to identify these issues" (Google Search Central).

That is why the check against the visible page matters.

If you would rather not hand-write JSON, the free schema markup generator builds Product JSON-LD you can paste into a page and then verify in the Rich Results Test.

Markup describes the page; it doesn't replace it

Structured data tells Google what a page offers. It doesn't make the page worth choosing. Shoppers, and the AI assistants some of them now ask for recommendations, still read the visible description. We cover what that copy needs in why Shopify product descriptions are invisible to AI.

Ready to optimize your search rankings?

XeoRank connects to Google Search Console, analyzes content gaps with AI, and gives you actionable fixes — from the terminal or dashboard.