Google Product Data: Category and Sale Date Guide

Google clarified category and sale-date markup for products. See the correct JSON-LD structure and an implementation checklist for ecommerce sites.

2026-08-18

On 7 July 2026, Google made two documentation updates for product pages that look small but have practical consequences. It added guidance for Product.category to merchant listing structured data and clarified how validFrom, validThrough and priceValidUntil should describe the active period of a sale price.

This is not a new ranking guarantee or a new required-property announcement. According to Google’s documentation changelog, the objective is to align product data on a web page more closely with category and sale-period information in Merchant Center. The real benefit for ecommerce teams is being able to give Google one consistent account of a product.

Products, barcodes, categories and sale periods being organised on a real ecommerce content desk

What does Product.category provide?

Google’s updated merchant listing documentation accepts two forms of category information:

  • Text: The merchant’s own product hierarchy, similar to the product_type field in Merchant Center.
  • CategoryCode: A Google Product Category identifier or path, similar to google_product_category in Merchant Center.

The two types can be combined, and multiple values can be supplied. An abbreviated JSON-LD example could look like this:

{
  "@context": "https://schema.org",
  "@type": "Product",
  "name": "City Running Shoe",
  "category": [
    {
      "@type": "CategoryCode",
      "inCodeSet": "https://www.google.com/basepages/producttype/taxonomy-with-ids.en-US.txt",
      "codeValue": "187"
    },
    "Sporting Goods > Running > Men's Running Shoes"
  ]
}

Your merchant-defined category preserves the hierarchy that works for customers and reporting. The Google category maps the item to a shared taxonomy. They do not have to replace one another.

How should a sale start and end be marked?

Google recommends validFrom for the beginning of a sale period and either validThrough or priceValidUntil for its end. Dates and times should use ISO 8601 format, preferably including the timezone.

When the active sale price is stored in Offer.price, the structure can look like this:

{
  "@type": "Offer",
  "price": "74.90",
  "priceCurrency": "EUR",
  "availability": "https://schema.org/InStock",
  "validFrom": "2026-08-18T00:00:00+02:00",
  "priceValidUntil": "2026-08-24T23:59:59+02:00",
  "priceSpecification": {
    "@type": "UnitPriceSpecification",
    "priceType": "https://schema.org/StrikethroughPrice",
    "price": "89.90",
    "priceCurrency": "EUR"
  }
}

If the sale price is held in a separate PriceSpecification, the dates should be placed on that object and validThrough should be used for the end. priceValidUntil is not valid for the PriceSpecification type. It is a small distinction, but placing the date on the wrong node can prevent Google from understanding the price relationship.

The three errors most likely to appear

1. The page, JSON-LD and Merchant Center disagree. If the customer sees EUR 74.90 while structured data carries an old or expired value, reliability suffers. Price should be generated from one trusted source.

2. The end date remains in the past. Google notes that a listing may not display when priceValidUntil has expired. The date must update automatically when a campaign changes.

3. Markup appears only after client-side JavaScript runs. Google recommends putting product structured data in the initial HTML. Dynamically generated markup can make Shopping crawls less frequent and less reliable, especially where price and stock change quickly.

Is this the same as consumer sale-pricing law?

No. Consumer pricing rules determine which reference price can legally be shown to a buyer. Google’s update describes how the current price, previous price and campaign period are communicated to a search system.

In a well-designed commerce system, both requirements meet at the same source of truth: the correct reference price is calculated, displayed on the page and then sent consistently to JSON-LD and Merchant Center. Three manually maintained price fields will eventually drift apart during a busy promotion.

A check you can run today

  1. Test the 20 highest-traffic product pages with Rich Results Test and the Search Console Merchant listings report.
  2. Compare the visible page price, JSON-LD Offer and Merchant Center record at the same moment.
  3. Store your own category path and Google Product Category as separate fields.
  4. Generate campaign start and end times, including timezone, from one source.
  5. Automatically test that old price, sale price and date fields all close together when a promotion expires.
  6. For product variants, verify that every price is connected to the right SKU, availability and URL.

Google does not guarantee a rich result merely because structured data is present. Correct markup still creates a clean technical foundation for search and shopping systems to understand a product. To review your product pages against this structure, see our technical SEO and ecommerce services, or contact us for an assessment using a representative set of products.