Structured Data
Product and Merchant Listing Structured Data in 2026: What Changed and How to Keep It Accurate
Google added product categories, sale dates, an adult content label and a stricter fake-review rule to its product markup documentation in 2026. Here's what to mark up, how to keep the page, the markup and the Merchant Center feed in step, and how to test it.
On this page
- What changed in 2025 and 2026
- Product snippet or merchant listing
- What to mark up on a product page
- Keep the page, the markup and the feed in step
- Reviews and ratings after July 2026
- Common mistakes
- How to test
- What DeepSpider.ai checks, and what it doesn't
- Frequently asked questions
- The short version
- Sources
A small outdoor shop runs a Black Friday sale. The rucksack page says £79 in big orange numbers, the old £89 crossed out next to it. The product markup in the page template still says 89.00, because nobody told the developer about the sale. The Merchant Center feed was updated on Thursday and says 79.00 GBP, but the sale end date in the feed is in the wrong time zone. On Monday morning the shop owner finds a handful of products disapproved in Merchant Center and has no idea which of the three sources Google believed.
That's what product structured data looks like in practice. The markup itself isn't hard. Keeping it true is the hard part, and in 2026 Google added several properties that give you more to keep true: product categories, sale start and end dates, an adult content label, and a sharper rule about fake reviews. This guide covers what changed, what to mark up, how to keep the page, the markup and the feed in step, and how to test it.
In short
Use merchant listing markup (Product with an Offer) on pages where people can buy from you. Mark up only what shoppers can see, keep it identical to your Merchant Center feed, put it in the initial HTML, and give sale prices a start and end date. The 2026 additions are optional unless they describe your products, apart from the adult label, which Google says you must use for adult-oriented products.
What changed in 2025 and 2026
Google's structured data documentation changes quietly, so it's worth reading its changelog rather than relying on memory. These are the product-related entries since early 2025, in date order.
| Date | What changed | Who should care |
|---|---|---|
| 13 February 2025 | Examples for sale, strikethrough and member prices, with priceType and the beta validForMemberTier property | Shops with sale or member pricing |
| 14 March 2025 | returnPolicyCountry added to return policy examples, as it is required for MerchantReturnPolicy | Anyone marking up returns |
| 10 June 2025 | Loyalty programme markup documented and return policies moved to their own page | Shops with a loyalty scheme |
| 11 July 2025 | Merchant-level return policies must sit under Organization markup; offer-level policies support only a subset | Anyone marking up returns |
| 12 November 2025 | Merchant shipping policy markup (ShippingService under Organization) documented | Shops with a standard shipping policy |
| 20 May 2026 | hasAdultConsideration added to merchant listing and product variant markup | Shops selling adult-oriented products |
| 7 July 2026 | Product.category with Text and CategoryCode, plus a new Sale duration section | Most shops |
| 24 July 2026 | Review snippet guideline against fake and undisclosed incentivised reviews | Anyone showing star ratings |
Most of these entries say the same thing in different words: Google wants your markup to carry the same data as a Merchant Center feed. The July 2026 entries say so directly. Category "aligns with the Google Merchant Center feed specifications for the product_type and google_product_category attributes", and Sale duration "aligns schema.org usage with the Merchant Center feed attribute sale_price_effective_date". The adult property, according to the May entry, "brings parity with the Merchant Center feed specification for the adult property".
Barry Schwartz covered the July change at Search Engine Roundtable the same day, and Roger Montti at Search Engine Journal read it the same way: the new category property is "closing a gap between what's marked up on the page and what's submitted through the Merchant Center feed". Neither addition is needed for eligibility. Category is listed as a recommended property, and the sale dates are optional details for shops that run sales.
Product snippet or merchant listing
Google treats product markup as two features with different rules. Product snippets are for pages where people can't buy directly, such as an editorial review. Merchant listings are for pages where shoppers can buy from you, and they unlock the richer shopping surfaces: popular products, the shopping knowledge panel and product annotations in Google Images.
The merchant listing guide is strict about two things. "Only pages where a shopper can purchase a product are eligible for merchant listing experiences, not pages with links to other sites that sell the product." And the offer must be an Offer, not an AggregateOffer, because "the merchant has to be the seller of the product".
That second rule catches more shops than you'd think. Brodie Clark described a large ecommerce client whose product pages used AggregateOffer instead of Offer in their Product markup. The Rich Results Test showed only product snippets for those pages, so they weren't eligible for merchant listings at all. He recommended inProductGroupWithID instead, and later Google's product variant markup, which brings us to the next point.
What to mark up on a product page
Start with the required properties for a merchant listing: name, image and an offers object with price and priceCurrency. The price is a number and, unlike product snippets, merchant listings need it to be greater than zero. Then add what you actually know: availability, brand, a GTIN, SKU, description, condition, and the new category. Google's advice in its product markup introduction is to give as much accurate product information as you have, "without concern for the exact experiences that will use it".
Here's a compact example for a product on sale. Every property exists on schema.org and in Google's merchant listing guide, and the category path is a real entry in Google's product taxonomy.
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Ridge 40 Rucksack",
"sku": "R40-GRN",
"gtin13": "5012345678900",
"image": [
"https://www.example.com/img/ridge-40-1x1.jpg",
"https://www.example.com/img/ridge-40-4x3.jpg",
"https://www.example.com/img/ridge-40-16x9.jpg"
],
"description": "A 40 litre walking rucksack with a ventilated back panel.",
"brand": { "@type": "Brand", "name": "Example Outdoor" },
"category": [
{
"@type": "CategoryCode",
"inCodeSet": "https://www.google.com/basepages/producttype/taxonomy-with-ids.en-US.txt",
"codeValue": "Luggage & Bags > Backpacks"
},
"Rucksacks > Day packs"
],
"offers": {
"@type": "Offer",
"url": "https://www.example.com/products/ridge-40/",
"price": 79.00,
"priceCurrency": "GBP",
"validFrom": "2026-11-20T08:00:00+00:00",
"priceValidUntil": "2026-11-30T23:59:59+00:00",
"priceSpecification": {
"@type": "UnitPriceSpecification",
"priceType": "https://schema.org/StrikethroughPrice",
"price": 89.00,
"priceCurrency": "GBP"
},
"availability": "https://schema.org/InStock",
"itemCondition": "https://schema.org/NewCondition"
}
} The GTIN above is a placeholder. Use your real one, in numerical form: Google says it doesn't support the URL form for GTINs.
Product category
The category property now takes plain text, a CategoryCode object, or a mix of both in one array. Plain text is your own category, the equivalent of product_type in a feed, and Google recommends keeping it under 750 characters. CategoryCode points at Google's product taxonomy: set inCodeSet to the taxonomy URL and codeValue to either the numeric ID or the full path with > between levels.
If you already send google_product_category and product_type in a feed, copy the same values into the markup rather than inventing a second classification. On schema.org, codeValue and inCodeSet are the only properties CategoryCode adds to the general DefinedTerm type, and they're the two Google's guide uses, so there's nothing else to fill in.
Sale duration
This is the change most shops will use. A sale price gets a start with validFrom and an end with either validThrough or priceValidUntil. Google's best practices are short: give both dates, make sure the start isn't after the end, and include the time and time zone.
Where you put the dates depends on where the sale price lives. If the price on the Offer is the current sale price, put the dates on the Offer, as in the example above. If the sale price sits in its own price specification next to a strikethrough price, put validFrom and validThrough on that specification, because "the priceValidUntil property isn't applicable to the PriceSpecification type".
One line in the property table is worth remembering: "Your listing may not display if the priceValidUntil property indicates a past date." A sale that ended in March but still sits in the template is lowkey easy to miss, because the page itself looks fine. If your platform can't remove the dates when a sale ends, it's safer to leave them out than to leave them stale.
Adult-oriented products
The hasAdultConsideration property is the one 2026 addition with a "must". If you sell products that Google's adult-oriented content policy covers, "you must use this property to label them as adult-oriented". Google Search supports one value, https://schema.org/SexualContentConsideration. Labelled products can still appear in Shopping ads and free listings, subject to age and country restrictions. If your shop sells nothing of the kind, leave it out.
Shipping, returns and loyalty
Policies that apply to the whole shop belong under Organization markup, usually on one page such as the homepage or a policy page: hasMerchantReturnPolicy for returns (Google made this explicit for merchant-level policies in July 2025), and hasShippingService with a ShippingService for shipping (documented since November 2025). Use offer-level shippingDetails and return policies only for products that differ from the standard, and know that they support fewer properties than the organisation-level versions. Loyalty programmes are defined once, separately, and the offer only carries the member price or points. Google says shipping and returns benefits for loyalty members aren't supported at the moment.
Google is also explicit about what wins when the same policy is defined in several places.
So if you configure returns in Merchant Center or Search Console, that setting beats your markup. Brodie Clark notes a practical consequence: Search Console may still flag missing hasMerchantReturnPolicy or shippingDetails in the merchant listings report when those settings live in Merchant Center. If Merchant Center is set up correctly, he says, you can safely ignore those warnings.
Variants
If a product comes in sizes or colours, use ProductGroup with hasVariant, variesBy and productGroupID, and give each variant its own Product with a unique SKU or GTIN. Google's variant guidelines, which Jasmine Drudge-Willson walks through at Schema App, add a requirement that's easy to miss: each variant must be selectable directly with its own URL, showing the right image, price and availability. She notes that before this markup existed, her team handled variants with AggregateOffer, with one Offer per SKU, or with ProductModel. The first of those is exactly the pattern Brodie Clark saw blocking merchant listings.
Keep the page, the markup and the feed in step
Merchant Center checks your feed against your pages. Its help page on price mismatches explains that Googlebot "routinely crawls your website landing pages and compares the price [price] attribute in your data source with the prices on your landing page or in your structured data markup". When they disagree, "the product with the mismatch may be disapproved". After you fix it, products are reapproved once Googlebot crawls them again, which can take hours or days.
A few rules from that page and the merchant listing guide decide most cases:
- Use the HTML your server returns. Merchant Center says Googlebot "crawls the data present in the HTML returned from your web server", and data added by JavaScript after load "will trigger an error". The merchant listing guide warns that JavaScript-generated markup "can make Shopping crawls less frequent and less reliable".
- Mark up what shoppers see. "Prices reflected in the HTML need to match exactly the prices uploaded in Merchant Center." The same page lists a price shown to users that differs from the price crawled by bots as a common cause of mismatches.
- Get the sale timing right. The same help page lists a wrong
sale_price_effective_datestart date or time zone as a common cause of an incorrect price. Copy one set of dates into both the feed andvalidFromandpriceValidUntil. - One currency per URL. If you sell in pounds and euros, use a separate URL for each currency.
- Watch for duplicates. Shopify's
structured_dataLiquid filter outputs aProduct, or aProductGroupwhen the product has variants. If an SEO or reviews app adds its ownProductblock on top, you can end up with two blocks that say different things. Pick one source and remove the other.
If you're curious why Shopping crawls matter for the rest of your site, our piece on how every Google crawler now shares one crawl budget explains how Storebot-Google draws on the same capacity as Googlebot.
Reviews and ratings after July 2026
The review snippet guidelines now say: "Don't include fake or undisclosed incentivized reviews on your page or in your structured data markup." The examples are reviews "that aren't based on a genuine experience" and reviews given for "money, discounts, vouchers, or free products" without clear, prominent disclosure. Schwartz pointed out that this brings the structured data rules more in line with Google Business Profile guidelines.
Note the word "undisclosed". The guideline doesn't ban reviews from people who got a free sample, as long as that's clearly said. A star rating built on freebies nobody mentions, though, is a big yikes.
The older review rules still apply too. The reviews and the aggregate rating you mark up must be visible on the page, you shouldn't aggregate reviews from other websites, and since November 2025 Google asks you to avoid "multiple ways of indicating what's being reviewed". Nest the review inside the Product, or use itemReviewed, not both.
Common mistakes
| Mistake | What happens | Fix |
|---|---|---|
| AggregateOffer on a page you sell from | Page only eligible for product snippets, not merchant listings | Use one Offer, and ProductGroup for variants |
| Price with a currency symbol or comma, such as "£149.00" or "24,99" | Google expects a number in price | Put a plain number in price and the code in priceCurrency |
| Old priceValidUntil left in the template | Listing may not display | Remove or update the date when the sale ends |
| Dates like 30/11/2026 | Not the ISO 8601 format Google asks for | Use 2026-11-30T23:59:59+00:00 |
| Markup added by JavaScript after load | Less frequent, less reliable Shopping crawls and possible mismatches | Put Product markup in the initial HTML |
| Markup price differs from visible or feed price | Items may be disapproved in Merchant Center | Update all three from one source of truth |
| Returns and shipping repeated on every offer | More to maintain, offer level supports fewer properties | Define standard policies once under Organization |
| Theme and app both output Product | Two conflicting blocks for one product | Keep one source and remove the other |
How to test
Google's own steps are a good order to work in. Validate a few templates with the Rich Results Test, fix critical errors, and consider the non-critical ones. Then publish and use URL Inspection to see the page as Google sees it, including whether it's blocked by robots.txt, noindex or a login. After that, watch the merchant listings and product snippets reports in Search Console. Google suggests checking them after the first deployment, after every template release, and when analysing traffic. Google notes that a drop in valid items without a matching rise in invalid items may mean the markup is no longer on your pages.
One page at a time isn't enough for a shop with thousands of products, because structured data problems usually live in templates. Geoff Kennedy at Sitebulb put it simply: a single template implementation "might populate structured data across thousands of pages", so you want a crawler that tests the whole site and groups issues by template. Screaming Frog's structured data tutorial makes a useful distinction there too: errors cover Schema.org problems and missing or broken required properties, while warnings are for recommended ones that "do not disqualify you from being eligible for rich snippets". Fix errors first, then decide which warnings describe information you actually have.
For the feed side, Merchant Center's Needs attention page is where mismatches are reported. A site crawler sees your pages, not your feed.
What DeepSpider.ai checks, and what it doesn't
DeepSpider.ai checks structured data on every audited HTML page, in the Structured Data / Schema topic. For product pages, these checks matter most:
- Invalid JSON-LD (Error): JSON-LD blocks in the source HTML that don't parse.
- Invalid property values (Warning): non-numeric prices and malformed dates in
priceValidUntil,datePublished,dateModifiedanddateCreated. A price written as "£149.00" or a date written as "30/11/2026" shows up here. - Type-specific field issues (Needs review): a
Productwithout a name, or without at least one ofoffers,revieworaggregateRating. - Rating and review inconsistencies (Warning): rating values outside their declared range, reversed bounds, or negative and non-integer counts.
- Unknown schema types or properties (Needs review): typos such as "priceValidUnitl", checked against a bundled Schema.org vocabulary that includes
CategoryCodeandhasAdultConsideration.
Two informational views, Structured data inventory and Pages without detected structured data, show which types each page carries and where markup is missing. Errors and Warnings count towards the Website Health Score; Needs review checks and the informational views don't.
It's just as important to know the limits:
- DeepSpider reads JSON-LD in the HTML your server returns. It doesn't run JavaScript, so markup injected later isn't checked. That's also roughly how Merchant Center reads prices, but it means a JavaScript-only setup shows up as missing.
- Microdata and RDFa are detected, not validated.
- It doesn't compare your markup with the visible price or with your Merchant Center feed, and it doesn't check whether a
priceValidUntildate is in the past, whethervalidFromandvalidThroughare valid dates, or whether the sale starts before it ends. Use Merchant Center and the Rich Results Test for those. - It isn't Google's rich result eligibility test. Passing every DeepSpider check doesn't guarantee a merchant listing, and missing optional properties such as
categoryaren't reported as failures.
If you want more on reading an audit like this without chasing every count, see why technical SEO audits need context, not just issue counts.
When to leave it alone
If your products already appear correctly in Shopping and your Merchant Center feed carries category, sale dates and policies, adding the same values to markup is good housekeeping, not an emergency. Do it at the next template change, and test before you ship.
Frequently asked questions
Do I still need markup if I have a Merchant Center feed?
Google recommends both. It says providing structured data and a feed "maximizes your eligibility to experiences and helps Google correctly understand and verify your data". Markup also helps pages that aren't in your feed, and some experiences combine the two.
Does product markup improve rankings?
Google doesn't describe it as a ranking factor. It makes pages eligible for richer results and shopping surfaces, which can change how many people click. Treat any claim of a direct ranking boost with caution.
Should I add Product markup to category pages?
Google recommends focusing on individual product pages rather than pages that list products. A category page isn't a specific product, so it isn't eligible for product rich results.
Should I use validThrough or priceValidUntil?
On the Offer, either works for the end of a sale. On a PriceSpecification, use validThrough, because priceValidUntil isn't a property of that type.
Is the new category property required?
No. It's a recommended property. It's most useful when you already maintain Google product categories and product types in a feed and want the page to say the same thing.
Can I mark up reviews from people who received a free product?
Yes, if the incentive is clearly and prominently disclosed. What the July 2026 guideline rules out are fake reviews and incentivised reviews that hide the incentive.
The short version
Product markup in 2026 is mostly about agreement. Google added category, sale dates and an adult label so your markup can carry the same facts as your Merchant Center feed. Use one Offer per product you sell, ProductGroup for variants, Organization markup for shop-wide shipping and returns, and put it all in the initial HTML. Give sales a start and an end, and remove the dates when the sale is over. Then test templates rather than pages, and let Merchant Center tell you when the feed and the page drift apart.
Sources
- Google Search Central: Latest Google Search documentation updates
- Google Search Central: Merchant listing (Product, Offer) structured data (updated 8 September 2026)
- Google Search Central: Introduction to Product structured data
- Google Search Central: Review snippet (Review, AggregateRating) structured data
- Google Merchant Center Help: How to fix: Mismatched product price
- Search Engine Roundtable (Barry Schwartz): Google Adds Product Category & Sale Duration To Merchant Listing Doc (7 July 2026)
- Search Engine Roundtable (Barry Schwartz): Google Review Snippets Prohibits Fake or Undisclosed Incentivized Reviews (27 July 2026)
- Search Engine Journal (Roger Montti): Google's New Merchant Listing Structured Data Improves SEO (9 July 2026)
- Brodie Clark Consulting (Brodie Clark): Merchant Listings in Google Search Console
- Schema App (Jasmine Drudge-Willson): Google Expands Structured Data Support for Product Variants
- Shopify: Liquid filters: structured_data
- Schema.org: CategoryCode and validThrough
- Sitebulb (Geoff Kennedy): A Practical Introduction to Structured Data for SEO
- Screaming Frog: Structured Data Testing & Validation