ProductGroup Schema Generator
Turn a list of sizes and colors into ProductGroup markup with hasVariant, one Product and Offer per variant.
Your details
Paste this on the product page (replacing any existing Product markup), then test it in Google's Rich Results Test
<script type="application/ld+json">
{
"@context": "https://schema.org/",
"@type": "ProductGroup",
"name": "Merino Crew Sweater",
"description": "Midweight merino wool crew neck sweater. Machine washable.",
"url": "https://example.com/products/merino-crew-sweater",
"image": "https://example.com/images/merino-crew.jpg",
"brand": {
"@type": "Brand",
"name": "Harbour & Co"
},
"productGroupID": "MCS-01",
"variesBy": [
"https://schema.org/size",
"https://schema.org/color"
],
"hasVariant": [
{
"@type": "Product",
"sku": "MCS-S-NAV",
"name": "Merino Crew Sweater - S / Navy",
"size": "S",
"color": "Navy",
"offers": {
"@type": "Offer",
"url": "https://example.com/products/merino-crew-sweater?size=s&color=navy",
"price": 89,
"priceCurrency": "USD",
"availability": "https://schema.org/InStock",
"itemCondition": "https://schema.org/NewCondition"
}
},
{
"@type": "Product",
"sku": "MCS-M-NAV",
"name": "Merino Crew Sweater - M / Navy",
"size": "M",
"color": "Navy",
"offers": {
"@type": "Offer",
"url": "https://example.com/products/merino-crew-sweater?size=m&color=navy",
"price": 89,
"priceCurrency": "USD",
"availability": "https://schema.org/InStock",
"itemCondition": "https://schema.org/NewCondition"
}
},
{
"@type": "Product",
"sku": "MCS-L-NAV",
"name": "Merino Crew Sweater - L / Navy",
"size": "L",
"color": "Navy",
"offers": {
"@type": "Offer",
"url": "https://example.com/products/merino-crew-sweater?size=l&color=navy",
"price": 89,
"priceCurrency": "USD",
"availability": "https://schema.org/OutOfStock",
"itemCondition": "https://schema.org/NewCondition"
}
},
{
"@type": "Product",
"sku": "MCS-S-OAT",
"name": "Merino Crew Sweater - S / Oatmeal",
"size": "S",
"color": "Oatmeal",
"offers": {
"@type": "Offer",
"url": "https://example.com/products/merino-crew-sweater?size=s&color=oatmeal",
"price": 89,
"priceCurrency": "USD",
"availability": "https://schema.org/InStock",
"itemCondition": "https://schema.org/NewCondition"
}
},
{
"@type": "Product",
"sku": "MCS-M-OAT",
"name": "Merino Crew Sweater - M / Oatmeal",
"size": "M",
"color": "Oatmeal",
"offers": {
"@type": "Offer",
"url": "https://example.com/products/merino-crew-sweater?size=m&color=oatmeal",
"price": 94,
"priceCurrency": "USD",
"availability": "https://schema.org/InStock",
"itemCondition": "https://schema.org/NewCondition"
}
}
]
}
</script>5 variants in one ProductGroup. Every offer URL must open the page with that variant already selected, showing its price, image and stock.
Shopify themes and WooCommerce SEO plugins often print their own Product markup. Replace it rather than adding a second block, or Google sees two conflicting products.
How ProductGroup markup works
Google treats a product with sizes or colors as a ProductGroup. The group holds what every variant shares (name, brand, description, parent SKU) and lists each variant as a Product under hasVariant, with its own SKU, option values and offer.
- variesBy names the options that change between variants. Google supports
size,color,material,pattern,suggestedAgeandsuggestedGender. This tool covers all except suggestedAge, which needs an age range rather than text. - productGroupID is your parent SKU. It must be unique.
- Each variant needs a unique ID (SKU or GTIN) and its own URL that opens the page with that variant already selected.
- url on the ProductGroup is only for single-page setups, where every variant lives on one product page. That's how Shopify and WooCommerce work by default.
The tool builds each offer URL for you: ?size=m&color=navy style parameters, WooCommerce's ?attribute_pa_size=m parameters, or Shopify's ?variant= ID from the last column.
Adding it to Shopify or WooCommerce
- 01
Check for existing markup
View the product page source and search for
"@type": "Product". Most themes and SEO plugins already print Product markup. Replace it rather than adding a second, conflicting block. - 02
Shopify
Go to Online Store → Themes, open the … menu and choose Edit code. The markup usually lives in the product section or a snippet. For a whole catalog, turn this output into Liquid that loops over
product.variants. - 03
WooCommerce
Use your SEO plugin's schema settings if it supports ProductGroup, or print the JSON-LD in
wp_headfor that product with a code snippets plugin. Variation URLs useattribute_pa_{slug}for global attributes, so check the slugs under Products → Attributes. - 04
Test it
Run the page through Google's Rich Results Test and check the Merchant listings report in Search Console after Google recrawls.
Optional: link each offer to your store-wide policies with the return policy and shipping generators. The offers then reference them by @id.
Common mistakes
- Variant URLs that don't preselect anything. Google needs each URL to show that variant's price, image and stock, and to let shoppers add it to the cart.
- Duplicate SKUs. Two variants with the same SKU look like one product to Google. The tool warns you.
- Markup that changes as shoppers click. Google says the markup on a single-page site shouldn't change when a different variant is picked. Print all variants in the initial HTML.
Questions people ask
Do I need ProductGroup if each variant is a separate product page?
Yes, but the markup differs. On multi-page setups, each page repeats the full ProductGroup and you leave out the group's url. This tool builds the single-page version, which is what Shopify and WooCommerce use.
Can I include GTINs?
Yes. Add the barcode as the column after the stock status. The tool accepts 8, 12, 13 or 14 digits and leaves out anything else with a warning.
What's the difference between productGroupID and inProductGroupWithID?
They carry the same parent SKU. Put productGroupID on the ProductGroup, or inProductGroupWithID on each variant. If you use both, they must match. This tool uses productGroupID.
Will this give me rich results?
It makes the page eligible for Google's merchant listing and product variant features. Google decides when to show them.
Related tools
Last reviewed 30 September 2026.
Sources: Google Search Central: Product variant structured data · Google Search Central: Merchant listing structured data · Shopify Liquid reference: product object (variant URL parameter)
