Product schema markup tells search engines, in a machine-readable way, what a product page says about name, image, price, availability and reviews. Set up correctly, it can make a page eligible for product rich results that show details like price and rating directly in search. This guide walks through mapping Product and Offer properties to visible content, testing for errors, and tracking every field in one template.
What Product Schema Markup Does
A person reading a product page can tell at a glance where the price is and whether the item is in stock. For a search engine, the same information is scattered through the layout. Structured data labels it explicitly using the schema.org vocabulary.
Google's documentation on Product structured data (Opens in a new tab) explains that this markup lets Google present product information in richer ways across Google Search and Google Images, with details such as price, availability, ratings and shipping becoming part of the result.
Two limits are worth stating up front:
- Eligibility is not display: correct markup makes a page eligible for rich results, but Google does not promise to show them every time.
- It is not a ranking lever: there is no documentation saying product structured data raises a page's position. Its effect is on how the result looks and what users learn before they click.
Within those limits, product markup still earns its keep. Shoppers see price and availability before clicking and are less likely to land on a page that does not match what they wanted. The same documentation notes that providing both structured data and a Merchant Center feed maximizes eligibility for shopping experiences.
Unlike article markup, product markup is a commercial data layer full of values that change often. If you want the editorial side, our guide to Article and FAQ schema markup covers it; this article stays focused on products.
Product Snippets vs Merchant Listing Experiences
Google uses product structured data for two different experiences, and the one you qualify for depends on the kind of page you run.
Merchant listing experiences are for pages where customers can buy the product from you. They support richer commercial detail such as apparel sizing, shipping and return policies. According to Google, only pages where a shopper can purchase a product are eligible.
Product snippets are for pages where people cannot buy the product directly: editorial reviews, comparison pages and aggregator sites. This experience leans toward review-focused fields such as pros and cons.
The two are not mutually exclusive. A product page that meets the required properties for merchant listings can also be eligible for product snippets. Search Console reflects the split with two reports: the Merchant listings report for pages where shoppers can buy, and the Product snippets report for other product-related pages like reviews and aggregators.
The practical decision is simple. An online store's product page should target merchant listing requirements. A blog post reviewing the most affordable headphones on the market should target product snippet requirements, and if it sells nothing, it should not fill in Offer fields as though it were the seller.
Product, Offer and AggregateRating Structure
Product markup is built from three types, each answering a different question:
- Product: what is this item? Identity details like name, image, description, brand, SKU and GTIN live here.
- Offer: on what terms is it sold? Price, currency, availability, condition, shipping and returns sit inside an Offer placed in the Product's offers property.
- AggregateRating: how have users rated it? The average rating and the number of ratings or reviews go here.
Individual reviews use the Review type inside the Product's review property. Aggregator pages listing prices from several sellers can use AggregateOffer, which carries a low and high price, instead of Offer. Note, though, that the product snippet documentation says to use Offer rather than AggregateOffer if you want to be eligible for the price drop enhancement.
On format, Google's general structured data guidelines (Opens in a new tab) list JSON-LD as the recommended format, with Microdata and RDFa also supported. JSON-LD's practical advantage is that the markup lives in a single block independent of your HTML layout, so template changes break it less often. Because it carries fast-changing values like price and availability, rendering that block server-side in the initial HTML also makes testing and debugging simpler.
Required and Recommended Properties
Required properties depend on which experience you target. The merchant listing structured data documentation (Opens in a new tab) breaks them down like this:
- Required on Product: name, image and offers.
- Required on Offer: price and priceCurrency (or their equivalents inside priceSpecification). Merchant listing experiences require a price greater than zero.
- Recommended on Product: aggregateRating, review, brand, description, one of the GTIN properties, mpn, sku, color, size, material, pattern, audience, category, hasCertification, isVariantOf and inProductGroupWithID, among others.
- Recommended on Offer: availability, itemCondition, shippingDetails, hasMerchantReturnPolicy, priceValidUntil, url, validFrom and validThrough.
Product snippets need less: name, plus at least one of review, aggregateRating or offers. The documentation adds that the Rich Results Test may warn when offers is used without review or aggregateRating.
Recommended does not mean optional in any practical sense. Required properties set the floor for eligibility; recommended ones help Google understand the product completely. Identifiers such as GTIN, brand and SKU in particular help match your product to the same item elsewhere. Give sku a single value, and give availability and itemCondition one value each.
Keeping Price, Availability and Shipping Consistent
The most common problem in product markup is not a missing field but inconsistent data. Markup that still shows the old price while the page shows a sale price, or says InStock when the item has sold out, produces a result that misleads shoppers.
To keep things consistent, generate the markup from the same data source that renders the visible value, not by hand. If the template that prints the price and the code that fills the JSON-LD read the same variable, drift between them becomes hard. Write the currency as an ISO 4217 code such as USD or EUR, and give the price as a number without a currency symbol.
For availability, use schema.org's ItemAvailability values, such as InStock, OutOfStock, PreOrder and BackOrder. When a product is temporarily sold out, updating availability rather than deleting the markup keeps it in line with the "out of stock" message on the page.
For shipping and returns, Google recommends defining a global policy at the Organization level if your business has a standard one. The shippingDetails and hasMerchantReturnPolicy properties inside Offer are for product-specific overrides or businesses without a standard policy. That saves you from repeating the same policy on every product page and updating hundreds of pages when it changes.
Consistency is not only a technical matter. Product copy should match the markup and the photos too. Our product description writing guide covers how to prepare copy with that in mind.
Marking Up Product Variants
For products sold in several colors or sizes, each option is its own product but belongs to the same parent. Google supports expressing that relationship with the ProductGroup type, and both product snippets and merchant listings support variants.
Three ProductGroup properties stand out. productGroupID identifies the parent, often thought of as the parent SKU. variesBy lists what distinguishes the variants, such as color, size, material, pattern, suggested age or suggested gender. hasVariant nests the variant Product items. Each variant can point back to the group with isVariantOf, or carry the group ID with inProductGroupWithID.
There are two common setups:
- Single-page: all variants are selected on one page, usually through query parameters. The ProductGroup must have one distinct canonical URL, and nesting the variants under hasVariant is the most compact representation.
- Multi-page: each variant has its own page. Each page then needs full, self-contained markup for the entities on it, which means repeating the ProductGroup definition on every page.
In both setups, each variant needs a unique ID in its markup, such as sku or gtin, and a distinct URL that opens with that variant preselected. Our guide to ecommerce filter URLs and faceted navigation covers the crawling side of parameter URLs; keep variant URLs and filter URLs clearly separated so one does not get managed like the other.
Rules for Review and Rating Markup
Ratings and reviews are the most frequently misused part of product markup. Google's review snippet documentation asks that marked-up reviews be readily available to users on the marked-up page, and that users can see the aggregate rating on the page.
AggregateRating requires ratingValue and at least one of ratingCount or reviewCount. If your rating scale is not the usual one, declaring the range with the scale properties prevents misreading.
A frequent question is self-serving reviews. The rule in the review snippet documentation reads that if the entity being reviewed controls the reviews about itself, its pages using LocalBusiness or any other type of Organization structured data are ineligible for the star review feature. That rule is written for reviews of the business itself; the documentation does not list product reviews under it, and Product is a supported review type. In practice, genuine customer reviews of a product, collected on your own site and shown on the page, can be marked up under Product.
What does cause trouble: marking up reviews users cannot see, copying ratings from other sites onto your product, publishing incentivized reviews without disclosure, and stamping the same fixed rating across every product. Pros and cons markup is a separate case: only editorial product review pages are eligible for that appearance, so merchant product pages and customer reviews do not qualify.
Matching Markup to Visible Content
Google's general structured data guidelines set two clear principles: do not mark up content that is not visible to readers, and make sure the markup is a true representation of the page content. For product markup, that means every value in the JSON-LD needs a visible counterpart on the page.
Run a field-by-field check. Is this price visible on the page in the same currency? Does this availability match the state of the buy button? Are this rating and review count displayed? Is this image in the product gallery? Does this brand name appear in the title or description?
Mismatches usually come from a handful of sources: a cached, outdated JSON-LD block; a sale price applied only in the visual layer; taxes added at checkout that differ from the marked-up price; or a plugin generating its own Product block that collides with one from the theme. The last one is common. When two Product blocks on one page carry different prices, it is unclear which one is right.
Google says it can apply a manual action for spammy structured data. According to the guidelines, such an action removes rich result eligibility but does not affect how the page ranks in web search.
Testing Tools and Search Console Reports
Check markup with several tools, before and after release:
- Rich Results Test: shows which rich results Google considers the page eligible for, along with critical errors and warnings. Critical errors block eligibility; fixing non-critical issues improves data quality.
- URL Inspection tool: shows how Google sees the live page and whether the markup is present after rendering.
- Merchant listings and Product snippets reports: group valid, warning and invalid items across the site. A template bug affecting hundreds of pages shows up here.
- Unparsable structured data report: catches syntax errors such as a missing bracket or comma.
- Schema Markup Validator: checks conformance with the schema.org vocabulary rather than Google-specific rules.
After a fix, you can start validation in the relevant Search Console report. Google notes that it can take several days after publishing for pages to be crawled and reprocessed, so changes do not show up instantly. A workable routine: test template changes with the Rich Results Test code input before release, test a few representative live product URLs afterwards, then watch how the invalid item count moves in Search Console. Repeat this after any release that touches price or stock logic.
Should Category Pages Carry Product Markup
Short answer: adding Product markup to category pages gains nothing for product rich results. Google's documentation says product rich results only support pages that focus on a single product (or its variants), and recommends adding markup to product pages rather than pages that list or categorize products.
Category pages have other options. BreadcrumbList can mark where the page sits in your site hierarchy. Beyond that, a category page's search visibility depends far more on content, internal linking and pagination than on markup. The technical side of pagination is covered in our guide to pagination on category pages.
On most ecommerce sites, category pages target the most competitive queries and need outside signals to compete. Link building aimed at those pages is covered in our guide to backlinks for ecommerce category pages, and planning for the whole site in our article on backlink strategy for ecommerce sites.
Imagine a hypothetical sportswear store that adds a separate Product block for every item on its category pages, while the same items are also marked up on their own pages. An audit finds the category blocks carry stale prices because of caching. The team removes Product blocks from category pages, keeps BreadcrumbList there, and limits product markup to product pages. The scenario is fictional; it illustrates how duplicated markup multiplies the risk of inconsistency.
Sample Template: Product Schema Field Map
Use this sample template to map each markup property to its visible counterpart and its data source; price and stock values are placeholders.
| Schema property | Status | Visible counterpart on page | Data source and note |
|---|---|---|---|
| Product.name | Required | Product title | Name field in the product table |
| Product.image | Required (merchant listing) | First gallery image | Crawlable, absolute URL |
| Offer.price | Required | Displayed selling price | Placeholder: [PRICE]; same variable as the visible price |
| Offer.priceCurrency | Required | Currency next to the price | ISO 4217 code, e.g. USD |
| Offer.availability | Recommended | Stock label and buy button | Placeholder: [STOCK]; InStock or OutOfStock |
| Product.sku and gtin | Recommended | Product details tab | Unique value per variant |
| Product.brand.name | Recommended | Brand in title or description | Brand table |
| AggregateRating | Recommended | Average rating and review count | Add only if shown on the page |
| Shipping and return policy | Recommended | Shipping and returns section | Global policy at Organization level |
Fill in the table once per product template and update it whenever the template changes. A row with an empty "Visible counterpart" column points either to information that should be added to the page or to a property that should be removed from the markup.
Frequently Asked Questions
Does product schema markup improve rankings?
No, there is no Google documentation saying product markup raises rankings. It makes pages eligible for rich results that show details like price, availability and ratings, and even then display is not certain.
Should I use JSON-LD or microdata?
Google supports JSON-LD, Microdata and RDFa, and lists JSON-LD as the recommended format. Because JSON-LD sits in a single block independent of the HTML layout, it is usually easier to maintain and test.
Should markup be removed when a product is out of stock?
If the product page stays live, update availability to a value such as OutOfStock instead of removing the markup, so it matches what the page says. If the product is gone permanently, decide separately what should happen to the page itself.
Can I mark up reviews collected on my own site?
The self-serving review rule in Google's review snippet documentation covers pages using LocalBusiness and Organization markup, not products. Genuine customer reviews of a product that are visible on the page can be marked up under Product; hidden or copied ratings should not be.
Should variants be marked up as separate products?
Each variant is marked up as its own Product, linked to a shared ProductGroup. Every variant needs a unique ID and a distinct URL that opens with that variant preselected.
Why are my product rich results not showing?
Eligibility does not mean display; Google may not show a rich result in every case. Check the Rich Results Test for critical errors, confirm the markup matches visible content, and review the Search Console reports. Changes can take several days to be reflected.
Conclusion and Next Step
Product schema markup starts with targeting the right experience: merchant listings for pages that sell, product snippets for review pages. Meet the required properties, enrich the data with recommended ones, map every value to its visible counterpart, and test regularly. If you want stronger product copy for that markup to rest on, take a look at our content writing service and compare the options with the details on the product page.
Post a comment
Please log in to leave a comment. Login