Google added category and sale-duration properties to merchant-listing schema. That's a convergence tax, not an upgrade.
Sources: Google Search Central; Google Merchant Center Help; schema.org; Search Engine Land; Search Engine Journal; Search Engine Roundtable.
The short version
- Google's July 7 additions to merchant-listing structured data (a Product.category property and a Sale duration section) align on-page schema with the product feed. For most merchants that is alignment burden, not a new ranking lever.
- category is not a required merchant-listing property. Its CategoryCode option lets you stamp a Google Product Category into the page, but GPC is override-only in the feed and Google auto-classifies every product, and the schema doc doesn't repeat that warning.
- First-hand: in one audit, a client had loaded its own taxonomy into google_product_category (Google's override field). Moving those values to product_type and letting Google auto-classify lifted organic Shopping clicks by roughly 20%. Over-populating the optional category fields can backfire.
- Sale duration is the useful half, but only if you avoid the silent offers.price-versus-priceSpecification trap and attach the sale window to the node that carries the active price.
- The durable move: generate every surface (feed, schema, breadcrumb, page) from one source of truth, so the convergence tax of newly shared properties stays near zero.
On July 7, 2026, Google added two properties to its merchant-listing structured data guide: Product.category, and a new “Sale duration” section for time-bound pricing.1 Both are useful, and both are being read the wrong way. The headlines frame them as an SEO upgrade. One outlet’s headline literally says the new structured data “improves SEO.”8 What Google actually did is narrower: it aligned what you can say in on-page schema with what you already say in your product feed. That alignment is a genuine convenience. For most merchants it is also one more thing that can silently fall out of sync.
The two changes are not equally valuable, so treat them separately. Sale duration is a real, implementable improvement with one well-known trap. Product.category is mostly harmonization, and the way Google documented it quietly re-imports the single most common product-feed anti-pattern onto a brand-new surface. Neither is a reason to panic, and neither is the “add this to rank better” story the coverage implies.
One product’s category can now be declared in as many as five places Google may read:
product_typeandgoogle_product_categoryin the feed,categoryas text and as aCategoryCodein the page schema, and yourBreadcrumbList. All five are supposed to agree.
What did Google actually add on July 7?
Two things, both in the merchant-listing structured data guide.1 First, a Product.category property for declaring a product’s category on the page itself. Second, a “Sale duration” section for putting a start and an end date on a sale price. Google’s changelog frames both as aligning schema.org with attributes you already send in the product feed: product_type and google_product_category for category, sale_price_effective_date for sale duration.2 Align is the operative verb throughout, and the change was widely reported the same week.79
Take category first. It now accepts two value types. As plain Text, it is your own category string, which Google explicitly calls “similar to the product_type attribute in product feeds.”1 As a CategoryCode object, it encodes a Google Product Category (GPC): you set inCodeSet to Google’s taxonomy URL and codeValue to the category ID ("2271") or the full path ("Apparel & Accessories > Clothing > Dresses").16 You can supply several values at once.
Is category a new ranking lever, or just harmonization?
Just harmonization, as far as anything Google has actually said. category is a recommended/optional property, not one of the fields merchant-listing eligibility rides on. Price, currency, availability, and identifiers do that work.17 Google already auto-classifies every product into its own taxonomy without any input from you, and the feed’s google_product_category exists only to override that classification in specific cases.3 Adding a page-level way to declare the same thing does not create a new signal so much as give an existing feed signal a second home.
For the large majority of catalogs, populating category in schema changes nothing about how a product ranks or whether it is eligible. The upside is real but small: one more surface stating the same fact, which helps only if that fact was previously ambiguous to Google. That is a narrow set of catalogs, and not the set the “improves SEO” framing is aimed at.
What doesn’t Google’s schema doc tell you about GPC?
The one thing that will bite people: google_product_category is override-only, and the schema page doesn’t say so. In the product feed, Google auto-classifies every product into its own taxonomy, so you are meant to submit a GPC only to correct a misclassification, target campaigns, or handle a regulated category like alcohol.3 Blanket-populating it is a long-standing anti-pattern: you override Google’s own classifier with hand-maintained codes that drift out of date.
I have watched this cost a client real traffic. In one audit, a merchant had loaded its own internal taxonomy into google_product_category, overriding Google’s classifier with category names that made sense to the business but not to how shoppers or the ranking systems group products, and it was hurting performance. We moved those values to product_type, where a merchant’s own taxonomy belongs, and let auto-classification own the GPC. Organic Shopping clicks rose roughly 20%. The rule of thumb that came out of it: populate the optional fields that help, but let auto-classification own categorization, because your internal business taxonomy is often not how a shopper or a search engine expects a product to be classified. CategoryCode moves that same override, and that same risk, onto the page.
Google’s new schema guidance shows you exactly how to stamp a GPC into your page via CategoryCode, but as of this writing it does not repeat the override-only warning.1 A merchant reading only the merchant-listing page has no way to know that hand-coding GPCs is usually the wrong move. The predictable result: teams read “Google now supports GPC in schema” as “we should add GPC to our schema,” cargo-culting the feed’s worst habit onto a new surface, and now maintaining those codes in two systems instead of one.
My recommendation is blunt. If you add category at all, prefer the plain-Text form that mirrors your product_type4 and your breadcrumb, and leave CategoryCode/GPC to the same narrow override cases where you would override it in the feed. Expressing a category is cheap. Maintaining a second, hand-curated Google taxonomy is not.
Why is category the hardest of the two to keep aligned?
Because category is not one field. It is a family of representations owned by different teams, and Google can now read all of them. Count the places a single product’s category lives. Feed ops own product_type and google_product_category in the feed. Whoever maintains your JSON-LD templates owns category, both as Text and as CategoryCode in the page schema. Merchandising and your CMS own the BreadcrumbList, its visible breadcrumb and its URL path. That is up to five machine-readable declarations of the same fact, sourced from three different teams, that are all supposed to agree.
This is the convergence tax. Every time Google lets the same product fact be declared in one more place, it adds another surface you have to keep in sync, and the bill comes due only for merchants whose feed, schema, and site taxonomy are authored separately rather than generated from one source. The expressiveness Google is adding is a gift. The reconciliation work is the tax. If your breadcrumb says “Home > Skincare > Moisturizers,” your product_type says “Skin Care > Face > Moisturizer,” and someone hand-stamps a GPC code into your schema, you have not given Google a clearer signal. You have given it three, and made it guess which one you meant.
How do you add category without creating a mismatch?
Generate category from one system rather than hand-authoring it in each place. Derive it everywhere it appears (feed product_type, schema category, and your breadcrumb) from one source of truth, such as your product information management (PIM) or catalog system, so feed ops, dev, and merchandising aren’t each maintaining a copy that drifts. Prefer the plain-Text form tied to the same field as your product_type, and reserve CategoryCode/GPC for the same narrow override cases you would use in the feed.
Two things are worth spelling out:
- Do not blanket-populate
CategoryCode/GPC. Reserve it for the cases where you would override GPC in the feed: a demonstrable misclassification, campaign targeting, or a compliance category. - If you already syndicate a clean catalog, you likely do not need to hand-add category to schema at all, because the feed already carries it. I wrote about why the catalog itself is becoming the substrate in Shopify’s catalog landgrab.
The test is simple: if you cannot point to the one system that generates your category everywhere it appears, adding another place to declare it makes your data worse, not better.
Is sale duration worth implementing?
Yes. Sale duration earns its keep, provided you avoid one silent trap. It lets you tell Google exactly when a promotional price starts and ends, which matters for time-boxed events like a Black Friday price that must not still show on December 1. The catch is an old one: if both offers.price and a priceSpecification encode a price, Google uses offers.price and silently ignores the priceSpecification. There is no validation error, just the wrong price.1 Layer a sale window on top and you can attach correct dates to the wrong, ignored node.
The clean pattern puts the active sale price on the Offer, the window on the Offer, and only the strikethrough (pre-sale) price in a priceSpecification:
{
"@type": "Offer",
"priceCurrency": "USD",
"price": 89.99,
"validFrom": "2026-11-27T00:00:00-05:00",
"validThrough": "2026-11-30T23:59:59-05:00",
"availability": "https://schema.org/InStock",
"priceSpecification": {
"@type": "UnitPriceSpecification",
"priceType": "https://schema.org/StrikethroughPrice",
"price": 129.99,
"priceCurrency": "USD"
}
}
Three things make or break it. First, put validFrom/validThrough on whichever node carries the active price. Here that is the Offer. If you instead omit offers.price and let a UnitPriceSpecification carry the live price, the window goes on that spec. Second, don’t put priceValidUntil on a PriceSpecification: Google says it doesn’t apply there, so it is a silent no-op.1 Third, include the timezone offset, because a sale that flips at local midnight will start or end on the wrong day if Google reads a bare timestamp as UTC. Separately, this window has to match your feed’s sale_price_effective_date and the price a shopper actually sees. A schema sale that starts before the feed’s does is a classic feed-to-page mismatch, and mismatches are what get products disapproved.5
What would change this read?
Two things. If Google states that category in schema affects merchant-listing eligibility or classification, or moves it into the required-properties list, then it becomes a lever and the “harmonization, not upgrade” read is wrong. And if Google adds the override-only caveat to the CategoryCode guidance, the cargo-cult risk I’m flagging mostly evaporates.
Until one of those happens, the defensible reading is the boring one. Sale duration is a useful, implement-it-carefully improvement. category is a convenience most catalogs don’t need to touch. The real cost of both is the convergence tax you pay if your product data isn’t already generated from one source. The merchants who benefit most from Google harmonizing the feed and the page are the ones who harmonized their own data first.
Terms defined here
- Convergence tax. The recurring maintenance cost merchants pay each time Google lets the same product fact be declared in one more place. When Google harmonizes the product feed and the on-page schema onto a shared vocabulary, as it did by adding category and sale-duration properties to merchant-listing structured data, it also adds another surface that must be kept in agreement. The expressiveness is the gift. The reconciliation work is the tax, and it is paid only by merchants whose feed, schema, and site taxonomy are authored separately instead of generated from one source.
Sources
- Google Search Central - Merchant listing (product) structured data documentation
- Google Search Central - What's new: category added to merchant listing structured data; Sale duration section (July 7, 2026)
- Google Merchant Center Help - Google product category [google_product_category] (override-only guidance)
- Google Merchant Center Help - Product type [product_type]
- Google Merchant Center Help - Product data specification (sale_price_effective_date; feed-to-page alignment)
- schema.org - CategoryCode
- Search Engine Land - Google merchant listings support sale duration and product category
- Search Engine Journal - Google's New Merchant Listing Structured Data Improves SEO
- Search Engine Roundtable - Google Supports Product Category & Sale Duration To Merchant Listing Structured Data
Recent developments
Related reading
This piece elsewhere