Guide : ProductGroup Schema

Comment utiliser ProductGroup schema to groupe product variants (size, color, material) with hasVariant, variesBy, and productGroupID — plus the item_group_id difference and pourquoi Bing doesn't prise en charge it.

Première publication : 27 juin 2026 · Dernière mise à jour : 3 août 2026 · Advanced
Langues

ProductGroup schema wraps a définir of Product variants — a shirt's sizes and colors — sous un parent so Google understands they're options of the même item, pas separate products. It's additive: every variant is encore a complet Product with its propre sku/gtin, price, and availability, and ProductGroup ties les ensemble with hasVariant (nested, single-page sites), variesBy (qui attributes differ), and productGroupID (the parent sku). The unique la plupart courant mistake is writing variesBy as plain strings — it doit utiliser complet schema.org URLs comme https://schema.org/color; in my testing the JSON-LD encore validates but the grouping doesn't trigger (Google doesn't document que échec mode, so vérifier it yourself). Two plus traps: productGroupID (on-page schema) n’est pas Merchant Center's item_group_id (a product-feed attribute) — separate systems, nothing auto-syncs les, so utiliser matching valeurs deliberately; and Bing doesn't consume ProductGroup markup at tout (per Microsoft's Fabrice Canel, Sept 2024, a reported statement, pas a Microsoft doc). My rule with tout schema holds ici: implement it parce que it earns vous a search fonctionnalité, pas parce que plus markup is automatically meilleur — it aids understanding and merchant-listing eligibility, it doesn't faire a variant rank.

TL;DR — ProductGroup (Google’s Feb 2024 addition) wraps variant Product objects sous un parent so Google understands “same item, different options.” It’s additive — chaque variant garde complet Product markup (sku/gtin, offers, image, availability). Lien les with hasVariant (nested, single-page sites) or isVariantOf + inProductGroupWithID (flat, multi-page sites); declare the varying axes with variesBy — qui doit utiliser complet schema.org URLs (https://schema.org/color), pas plain strings (the #1 implementation mistake — validates soit façon, but grouping quietly won’t trigger En pratique, qui isn’t a documented Google behavior); and share a productGroupID (plain text parent sku, pas une URL). productGroupID is pas Merchant Center’s item_group_id — separate systems, nothing auto-syncs les, so utiliser matching valeurs on objectif. Seulement name is strictly requis. And Bing doesn’t consume ProductGroup at tout (Fabrice Canel, Sept 2024). Schema aids understanding and merchant-listing eligibility — it isn’t a ranking factor.

Où ce sits

Ce is the schema-implementation deep dive — the complet JSON-LD, the property-by-property référence, the Merchant Center reconciliation, and the troubleshooting. The upstream strategy question — devrait a donné variant obtenir its propre indexable URL at tout, and how do Shopify/WooCommerce/BigCommerce/Magento differ — is its propre topic (product variant SEO). Ce article assumes you’ve déjà made ceux calls and now besoin the markup correct. It aussi sits sous the broader balisage de données structurées and données structurées hubs, and it’s a sibling of Product schema (pour a unique, non-varying item, plain Product is tout vous besoin — ProductGroup is pour a family of variants).

Pourquoi ProductGroup exists

Google’s propre framing: “To aider Google meilleur comprendre qui products are variations of the même parent product, utiliser the ProductGroup class with associated properties variesBy, hasVariant, and productGroupID to groupe tel variants ensemble.” The motivating categories are exactly ce que you’d expect — “apparel, shoes, furniture, electronic devices, and luggage… sold in différent variations (Par exemple various sizes, colors, materials, or patterns).”

Evidence for this claim Google documents ProductGroup relationships including variesBy, hasVariant, productGroupID, and inverse variant references. Scope: Google Search product-variant requirements; use the pattern matching the site's URL architecture. Confidence: high · Verified: Google: Product variants

The payoff is eligibility, pas ranking: “Ajout ce markup aussi rend votre products eligible pour afficher with variant information in merchant listing experiences.” Même caveat que s’applique to tout données structurées — it aids understanding and rich-result eligibility, it doesn’t déplacer vous up le résultats.

It’s additive — ce is the mental model que empêche la plupart mistakes

ProductGroup wraps Product; it doesn’t replace it. The ProductGroup object itself isn’t offered pour sale — it has aucun unique price, parce que “the coat” costs différent amounts selon qui variant vous buy. Every variant remains a complet Product with its propre sku/gtin, image, offers, and availability. Si vous trouver yourself trying to put a unique offers/price on the ProductGroup, arrêter — that’s the tell que you’ve confused the wrapper pour the chose being sold.

Evidence for this claim ProductGroup groups variant Product entities; it does not replace the Product data required for individual variants. Scope: Google Search product-variant guidance; each purchasable variant retains its relevant Product and Offer data. Confidence: high · Verified: Google: Product variants

The three core properties

ProductGroup adds the parent relationship; it never replaces the Product markup on each sellable variant. Source : Patrick Stox

A ProductGroup named Wool winter coat declares productGroupID 44E01 and variesBy values using full schema.org URLs for color and size. It connects to green small, green large, and blue small Product variants. Every variant keeps a unique SKU, Offer, image, and availability. The connection can use hasVariant in a nested model or isVariantOf in a flat model.

© Patrick Stox LLC · CC BY 4.0 ·

hasVariant (and isVariantOf)

hasVariant is “a nested Product property que is un of the variants of the ProductGroup property… A ProductGroup typically has multiple nested variant Product properties.” Vous put votre variant Product objects à l’intérieur the groupe.

The inverse aussi exists: “a variant Product property peut référence back to its parent ProductGroup en utilisant the isVariantOf property on the Product property.” Qui un vous utiliser dépend on votre site’s Structure d’URL (suivant section).

variesBy — complet schema.org URLs, pas plain strings

variesBy declares “aspects by qui the variants in the ProductGroup vary (pour exemple, size or color).” The critical detail, verbatim from Google’s properties table: “Référence ces variant-identifying properties via leur complet Schema.org URL.”

Que signifie:

"variesBy": ["https://schema.org/size", "https://schema.org/color"]

pas "variesBy": ["size", "color"]. Ce is the unique la plupart courant implementation mistake in ce entier topic. What’s documented: Google’s property table exige the complet URL formulaire — nothing plus spécifique que que. What’s pas documented: Google doesn’t publish ce que se produit si vous skip it. In my propre testing and consistent with autre practitioners’ reports, the JSON-LD encore passes syntax validation and nothing errors out, but the enhanced grouping behavior doesn’t trigger — treat que as a strongly observed pattern, pas an official Google statement, and vérifier it contre votre propre markup plutôt que taking it as gospel.

The pris en charge dimensions are https://schema.org/color, https://schema.org/size, https://schema.org/suggestedAge, https://schema.org/suggestedGender, https://schema.org/material, and https://schema.org/pattern.

productGroupID — plain text, and pas item_group_id

productGroupID is “the identifier of the product groupe (aussi connu as the parent sku). Ce identifier doit be provided pour the ProductGroup property or, alternatively, en utilisant inProductGroupWithID property pour variants.” It’s a plain text identifier — Google’s propre exemple is "44E01"pas une URL. Don’t over-generalize the variesBy “full schema.org URL” rule to ce field; they’re différent rules pour différent jobs.

Un hard constraint: “Si vous provide the identifier pour les deux the ProductGroup property and its variant Product properties, ils doit match.” Google’s docs state the requirement but don’t document ce que se produit quand it’s violated. Fondé on my propre testing (pas a documented Google échec mode), a typo or a template/environment leak que changements the valeur on un variant page drops que variant out of the groupe with aucun visible error — lune page simplement arrête being lire as partie of the family. Treat que as observed behavior worth verifying yourself, pas an official spec.

Two implementation patterns: nested vs. flat

Votre Structure d’URL decides qui pattern vous utiliser.

Single-page sites — nested (hasVariant). Tout variants are selectable on un URL (via dropdowns/swatches). “Pour single-page websites seulement: L’URL (sans variant selectors) où the ProductGroup property is located.” There’s exactly un canonical URL pour the whole groupe, and vous nest every variant Product à l’intérieur the ProductGroup via hasVariant.

Multi-page sites — flat (isVariantOf + inProductGroupWithID). Chaque variant has its propre dedicated URL. Ici “ce doesn’t appliquer since là is aucun unique URL canonique representing the ProductGroup property.” Chaque page doit carry complet, self-contained markup pour the entities défini on que page — vous don’t share un block à travers pages. Every variant Product références its parent with isVariantOf, and the groupe lien is carried by inProductGroupWithID: “Chaque product groupe doit have a unique ID in its corresponding données structurées markup, specified with the inProductGroupWithID property.”

Soit façon, “Chaque variant doit have a unique ID in its corresponding données structurées markup (Par exemple, en utilisant the sku or gtin properties).”

Un plus requirement personnes miss on multi-page setups: variants doit be reachable by a distinct, preselectable URL. Google: “Le site doit have the ability to preselect chaque variant directement with a distinct URL (en utilisant URL requête parameters), Par exemple https://www.example.com/winter_coat/size=small&color=green.” A variant que seulement apparaît après a client-side click, with aucun URL to point at, can’t be validated or indexé as its propre chose.

  • Requis on ProductGroup: simplement name (e.g., "Wool winter coat").
  • Recommended: variesBy, hasVariant, productGroupID, brand, description, aggregateRating, review, hasAdultConsideration, and (single-page sites seulement) url.

Technically seulement name is requis — but variesBy and productGroupID are functionally load-bearing. Skip les and the JSON-LD validates pendant que the grouping behavior vous wanted jamais montre up. (aggregateRating and review ici are the même types you’d utiliser standalone — voir the AggregateRating and Examiner schema deep dives.)

productGroupID vs. Merchant Center’s item_group_id — the reconciliation nobody explique

Ce is the confusion point que la plupart competitor content skips entirely, so it’s worth being precise.

  • productGroupID is a schema.org / on-page données structurées field. It feeds organic Search’s understanding of lune page.
  • item_group_id is a Google Merchant Center product-feed attribute. Merchant Center: “Utiliser the item groupe ID [item_group_id] attribute to groupe product variants in votre product données.” It feeds Shopping ads and free listings.
Evidence for this claim Merchant Center item_group_id groups variants in product data, while ProductGroup.productGroupID and Product.inProductGroupWithID are on-page structured-data properties. Google's docs cross-reference the concepts but do not establish automatic synchronization or a universal requirement that the literal values match across feed and markup. Scope: product data Confidence: high · Verified: Item group ID [item_group_id]

Ils are two separate systems, and Google fait pas automatically sync les. Meilleur pratique — and ce is echoed à travers the meilleur third-party implementation guides — is to utiliser the même identifier valeur pour les deux, so votre feed and votre markup agree on qui SKUs belong ensemble. A mismatch doesn’t necessarily break soit system outright, but it removes the reinforcing signal and peut produce inconsistent grouping entre Shopping surfaces and organic résultats enrichis.

(A footnote on casing: Merchant Center’s aider parfois writes productGroupId lowercase-d où Search Central’s docs utiliser productGroupID. That’s a cosmetic inconsistency in Google’s propre docs, pas a mistake on votre fin — follow Search Central’s productGroupID in votre JSON-LD.)

The consistency discipline ici is the même un que governs canonicals and variant URLs généralement: votre signals devrait agree with chaque autre, or you’re handing Google a raison to guess.

Bing ne fait pas prise en charge ProductGroup

Here’s the differentiator la plupart guides obtenir incorrect or omit: Bing ne fait pas currently consume schema.org ProductGroup markup. Microsoft’s Fabrice Canel, responding directement to a question à propos de si Bing supports schema.org/ProductGroup, said Bing ne fait pas yet prise en charge it, but que it’s “on our radar” and the team is “closely monitoring its adoption.” (Reported by Moteur de recherche Roundtable, covering a September 2024 exchange on X — a secondary report of a first-party statement, pas a Microsoft doc, so treat it as tel.)

Bing’s Webmaster Outils structured-data aider is a generic overview of pris en charge formats with aucun ProductGroup-, variesBy-, or productGroupID-spécifique content. Bing’s Shopping variant grouping runs via a feed-side itemGroupId field in Microsoft Advertising — the analog of Google’s item_group_id, pas on-page schema. So: implement ProductGroup pour Google, and handle Bing Shopping variants via the Microsoft Advertising feed, pas markup.

A remarque on dynamic markup

Google’s propre caution: “Be aware que dynamically-generated markup peut faire Shopping crawls moins frequent and moins reliable, qui peut be an problème pour fast-changing content comme product availability and price.” Si votre variant offers/availability are JS-injected, weigh que contre server-rendering the markup pour the fields que modifier souvent.

Validate avant vous ship

  • Résultats enrichis Tester — checks eligibility and surfaces required-property errors pour the merchant-listing/variant experience.
  • Balisage de données structurées Validator (schema.org) — validates the ProductGroup/Product types themselves, independent of Google fonctionnalités.
  • Search Console — the merchant-listings/product-snippet enhancement reports montrer eligibility and errors at scale post-deploy; Inspection d’URL montre how a spécifique page was lire.

Remember ce que “valid” fait and doesn’t tell vous: a plain-string variesBy passes validation and, in my testing, encore doesn’t trigger grouping. Validation catches syntax and required-property gaps, pas ce kind of semantic échec (qui Google doesn’t document soit façon) — pour ceux, vérifier by hand que votre variesBy valeurs are complet URLs and votre productGroupID matches à travers the groupe.

Pour où ce fits the bigger picture, voir the broader données structurées and schema markup hubs ce article lives sous.

Add an expert note

Pin an expert quote

New person? Create their unclaimed profile at /admin/experts/ → Pin a quote first.