Resources / Structured data / Template
ProductGroup and Product Variant JSON-LD Template
Connect a parent product to selectable variants with explicit variation properties, identifiers, URLs, and offers.
What this describes
Use ProductGroup when multiple Product entities are variants of one parent product, such as different colors, sizes, materials, or capacities. This example nests two variants on one page. A multipage implementation requires additional URL and canonical decisions; follow the provider guidance for that architecture.
Copyable template
{
"@context": "https://schema.org",
"@type": "ProductGroup",
"@id": "https://www.example.com/products/example-shirt/#group",
"name": "Example Shirt",
"description": "The shared description shown for this product family.",
"url": "https://www.example.com/products/example-shirt/",
"productGroupID": "SHIRT-100",
"brand": {
"@type": "Brand",
"name": "Example Brand"
},
"variesBy": [
"https://schema.org/color",
"https://schema.org/size"
],
"hasVariant": [
{
"@type": "Product",
"sku": "SHIRT-100-BLU-M",
"name": "Example Shirt — Blue, Medium",
"color": "Blue",
"size": "M",
"image": "https://www.example.com/images/shirt-blue.jpg",
"offers": {
"@type": "Offer",
"url": "https://www.example.com/products/example-shirt/?color=blue&size=m",
"priceCurrency": "USD",
"price": "39.00",
"availability": "https://schema.org/InStock"
}
},
{
"@type": "Product",
"sku": "SHIRT-100-GRN-M",
"name": "Example Shirt — Green, Medium",
"color": "Green",
"size": "M",
"image": "https://www.example.com/images/shirt-green.jpg",
"offers": {
"@type": "Offer",
"url": "https://www.example.com/products/example-shirt/?color=green&size=m",
"priceCurrency": "USD",
"price": "39.00",
"availability": "https://schema.org/OutOfStock"
}
}
]
}
Customize it
- Put facts shared by every variant on
ProductGroupand distinguishing facts on eachProduct. - Use
variesByURLs for the exact properties that create selectable variants. - Give the group and every variant stable, unique identifiers.
- Make each offer URL resolve to the represented selection, even when query parameters select it.
- Keep variant markup synchronized with the visible selection, canonical strategy, inventory, and feed data.
The sample SKU identifies a sellable variant, while an @id identifies a graph node. Give each represented variant a stable @id in a production implementation; do not use the group @id for every color and size simply because the variants share a page.
Validate it
Use the live-page JSON-LD validation tutorial and test every represented selection. Use Schema.org Validator and Google’s Rich Results Test, then compare the rendered markup with the product page and feed. Test the blue, medium selection against the corresponding variant object and its offer, then repeat for each material selection. A single-page and multipage variant architecture require different checks.
Official references
Completion check
- Confirm each Product is a true variant of the same parent.
- Match variesBy to the properties that distinguish the variants.
- Verify every variant URL, identifier, price, and availability.