In short. Use AggregateOffer for multiple offers of one product and ProductGroup with Product entities for its variants.
Definition:
AggregateOfferdescribes multiple offers associated with one product, such as offers from different merchants. Google Search Central says not to use it for a set of product variants, which should useProductGroupandProductstructured data.
Key facts
- Google's product snippet documentation accepts
OfferorAggregateOfferfor a product'soffersproperty. - Google defines
AggregateOfferas an aggregation of other offers, gives multiple merchants as an example, and explicitly excludes a set of product variants. - For an
AggregateOffer, Google listslowPriceandpriceCurrencyas required properties. It recommendshighPriceandofferCount. - Google's product variant documentation groups variations with
ProductGroup,variesBy,hasVariant, andproductGroupID, alongsideProductmarkup. - Each variant needs a unique identifier such as
skuorgtin, and the product group needs its own identifier.
What does AggregateOffer describe?
Google's AggregateOffer guidance defines the type as an Offer that aggregates other offers. Its example is one product sold by multiple merchants. Schema.org gives the same boundary: AggregateOffer applies when one product has multiple offers, such as the same shoes offered by different merchants.
The values summarize the offers in that group. lowPrice is the lowest available offer price, highPrice is the highest, and offerCount is the number of offers. Google requires priceCurrency in three-letter ISO 4217 format alongside lowPrice for this product snippet markup.
"offers": {
"@type": "AggregateOffer",
"offerCount": 5,
"lowPrice": 119.99,
"highPrice": 199.99,
"priceCurrency": "USD"
}
This pattern summarizes offers for one product. It does not identify size, color, material, or another product-changing property.
How should product variants be represented?
Google's product variant documentation says to use ProductGroup to group products that are variations of the same parent product. variesBy names the dimensions, hasVariant nests each Product, and productGroupID identifies the group. Google lists color, size, suggested age, suggested gender, material, and pattern as supported variesBy properties.
The individual Product describes the purchasable variant. Google says its name should be more specific than the group name, and its example gives each light blue coat variant its own size, URL, price, and Offer. The same documentation says to add ordinary Product structured data alongside the variant properties. Schema.org describes ProductGroup as a group whose products vary in well-described ways and says the group itself is not directly offered for sale.
{
"@type": "ProductGroup",
"productGroupID": "44E01",
"variesBy": [
"https://schema.org/size",
"https://schema.org/color"
],
"hasVariant": [
{ "@type": "Product", "name": "Small light blue coat" }
]
}
Google also documents the reverse relationship: a variant Product can point to its parent with isVariantOf when the variants are defined separately from the ProductGroup.
What changes for a single-page or multi-page site?
For a single-page site, Google's technical guidelines require one distinct canonical URL for the overall ProductGroup. Each variant must still have a distinct URL that can preselect it. That URL should show the corresponding image, price, and availability and let a shopper add the selected variant to the cart.
For a multi-page site, each page needs full, self-contained markup for the entities defined on that page. Google says the ProductGroup definition must be repeated on each variant page because no single canonical URL represents a group distributed across equally important pages. Each variant and each group also needs a unique identifier in its corresponding markup.
How should you check the markup?
First decide whether the values describe several offers for one product or several products that vary by a product property. Use AggregateOffer for the first case, with the price range and offer count. Use ProductGroup and variant-level Product entities for the second case, with the group's identifier and variant relationships.
Google's implementation steps call for adding the required properties, validating the code in the Rich Results Test, deploying pages, and using URL Inspection to test how Google sees them. For variant pages, check that the selected URL changes the displayed image, price, and availability with the variant and that the page's Product data remains complete.
Related terms
- AggregateOffer structured data
- ProductGroup structured data
- Product structured data
- How should product variants be represented in structured data?
FAQ
Can one AggregateOffer summarize the prices of size or color variants?
No. Google's product snippet documentation explicitly reserves AggregateOffer for an aggregation of offers and says not to use it for a set of product variants. Mark each variant as a Product under a ProductGroup, with its own offer data.
When is AggregateOffer appropriate?
Use it when one product has multiple offers, for example when the same product is offered by different merchants. lowPrice, highPrice, and offerCount summarize that offer set.
Does ProductGroup replace Product structured data?
No. Google's variant documentation says to add Product structured data in addition to the product variant properties. The group describes shared and variant relationships, while each Product carries the individual variant's details.
Sources
- Google Search Central, "Product snippet (Product, Review, Offer) structured data", updated 8 September 2026
- Google Search Central, "Product variant structured data (ProductGroup, Product)", updated 8 September 2026
- Schema.org, "AggregateOffer", undated
- Schema.org, "ProductGroup", undated
Check how a page reads to answer engines. Open the GEO score analyzer