October 26, 2026 • 12 lectura mínima

ProductGroup Schema for a Dropshipping Store

Map supplier variants to ProductGroup markup, keep stock and group IDs aligned with the feed, and validate the rendered page.

ProductGroup schema tells Google that one product has several variants. It lists sizes, colors, or other options under a parent group. On a dropshipping store, it's only as accurate as the data your supplier and import app keep current.

Print-on-demand apparel is nothing but sizes and colors. I ran a Shopify store that sold it, so variant data is the first thing I read in any catalog. The goal here is accurate markup on the products that matter, without adding a second block your theme doesn't need.

Key takeaways

  • Check 1 rendered page source before adding ProductGroup markup.
  • Match supplier option names to 6 supported variesBy values.
  • Give every variant a unique stock keeping unit and link.
  • Mark sold-out variants OutOfStock and remove delisted ones.
  • Set your import app to zero or remove sold-out variants.
  • Use one group ID in your markup and feed.

Because the import app decides which colors and sizes reach your store, our AliExpress-to-Shopify guide covers the apps that control that step.

What is ProductGroup schema?

ProductGroup schema declares one parent product and connects its variants through hasVariant, variesBy, and productGroupID. Google can then read each size or color as part of one product instead of as an unrelated item. This structure follows the schema.org ProductGroup definition and Google's supported group properties.

Each property has a separate job:

  • hasVariant names each product that belongs to the group.
  • variesBy names the supported characteristic that changes between variants.
  • productGroupID gives the parent group one textual identifier.

The parent can hold facts shared by every variant. Each variant remains a full Product with its own offer, identifier, and availability, so the group adds structure without replacing product schema.

When a shared fact changes, edit the parent. A change to size, price, link, or stock belongs on the variant. A variant-only fact placed on the group looks true for every option.

Use a group only when the items differ in well-described ways. A two-shirt bundle contains two products, but it isn't a size or color variant of one shirt.

Why supplier-fed variants break markup

A supplier-fed variant list is only as accurate as the last successful sync between the supplier, import app, and store. The supplier decides which options exist and whether they're stocked. Your import app decides which of those changes reach Shopify, while the theme describes the product record Shopify currently holds.

That chain creates a quiet failure. A supplier can delist XL while a no-action sync setting leaves XL available in the store. The markup then repeats the stale state.

A stale variant also creates the Product schema mismatch between what a page claims and sells. The repair point is the variant record that produced it.

I audit the store's variant list, then confirm supplier stock separately. This gap doesn't apply when you author the catalog and control the stock record yourself.

Trace the disagreement back through these records:

  1. Check whether the supplier still lists the option and shows stock.
  2. Read the option mapping and stock action in the import app.
  3. Open the variant in Shopify and confirm its quantity and SKU.
  4. View the page source and compare the marked-up state.

The first record where the values split is where you make the repair. Changing a later record by hand may hide the issue until the next supplier sync overwrites it.

The Supplier-Variant Sequence

The Supplier-Variant Sequence takes a product from unknown theme output to checked group markup in five dependent stages. Each stage produces the input needed by the next one:

  1. Check: Find what the theme already outputs.
  2. Map: Match supplier options to supported properties.
  3. Identify: Give each variant its own ID and link.
  4. State: Decide whether each variant stays, sells out, or leaves.
  5. Match: Align the group ID with the feed and validate.

Finish the check at each stage before moving to the next one.

1. See what your theme already outputs

Shopify's structured_data filter outputs a ProductGroup when a product has one or more variants. Shopify's reference Dawn theme prints that filter inside an application/ld+json script. Inspect the page source before adding markup.

A theme, app, or custom snippet can write its own JavaScript Object Notation for Linked Data (JSON-LD) block. Two blocks for the same product can disagree about its options, price, or stock. Shopify documents what the structured data filter returns, but it doesn't say that every theme uses it.

Run the check on a product with several variants:

  1. Open the product page and view its page source.
  2. Search for ProductGroup and application/ld+json.
  3. Count the product-related JSON-LD blocks.
  4. Compare their options and variants with the product in Shopify.
  5. Identify whether the theme, an app, or custom code wrote each block.

Write an owner beside every block you find. A theme block usually points back to a Liquid template. An app block often uses the app's name or a snippet it installed.

If ownership is unclear, disable nothing. Copy the block's opening lines and trace that text in the theme code or app settings first.

I wouldn't add a new block until I knew who owned the existing one. A product with no variants gets a plain Product from Shopify's filter, while an older or custom theme may print nothing.

2. Map supplier options to variesBy

Google supports six full schema.org URLs for variesBy, so declare only supplier options that map to those values. Its variant markup guide lists color, size, suggested age, suggested gender, material, and pattern.

Shopify accepts names you type but caps a product at three options. Your product can therefore use at most three of Google's six values, even when the supplier sends more labels. Merchant Center also expects the matching standard attribute beside the variant option.

Use this mapping as a translation layer:

variesBy URLSupplier option may sayMerchant Center attribute
https://schema.org/colorColor, Colour, Shadecolor
https://schema.org/sizeSize, Shoe Sizesize
https://schema.org/materialMaterial, Fabricmaterial
https://schema.org/patternPattern, Printpattern
https://schema.org/suggestedGenderGender, Departmentgender
https://schema.org/suggestedAgeAge, Age Groupage_group

‍

The middle column pairs common supplier labels with the closest supported property. Normalize Colour to color in the markup, for example, while leaving the buyer-facing label alone when it reads naturally.

If the only option is Style or Bundle, keep it visible to shoppers but don't force it into variesBy. Google's documentation is silent on unsupported options, so use the Rich Results Test output as the boundary. Don't rename a bundle as size merely to fill the property because the markup would describe the wrong difference.

3. Give every variant an ID and a URL

Every variant needs its own stock keeping unit (SKU) or Global Trade Item Number (GTIN) and a direct link. Google accepts either identifier in the variant's markup. Shopify variant links end in ?variant= followed by the variant ID.

The group gets a separate parent ID. Put it in productGroupID, or use inProductGroupWithID on every variant. Nested variants sit under hasVariant, so one group ID joins them while their SKUs keep them distinct.

This illustrative two-size hoodie uses the nested, single-page shape and JSON-LD that Google recommends.

{
  "@context": "https://schema.org/",
  "@type": "ProductGroup",
  "name": "Everyday Pullover Hoodie",
  "productGroupID": "HOODIE-100",
  "variesBy": ["https://schema.org/size"],
  "hasVariant": [
    {
      "@type": "Product",
      "name": "Everyday Pullover Hoodie, Medium",
      "size": "M",
      "sku": "HOODIE-100-M",
      "offers": {
        "@type": "Offer",
        "url": "https://example.com/products/everyday-hoodie?variant=10001",
        "price": "42.00",
        "priceCurrency": "USD",
        "availability": "https://schema.org/InStock"
      }
    },
    {
      "@type": "Product",
      "name": "Everyday Pullover Hoodie, Large",
      "size": "L",
      "sku": "HOODIE-100-L",
      "offers": {
        "@type": "Offer",
        "url": "https://example.com/products/everyday-hoodie?variant=10002",
        "price": "42.00",
        "priceCurrency": "USD",
        "availability": "https://schema.org/OutOfStock"
      }
    }
  ]
}

Replace every sample value with the product's visible data. Keep the group ID fixed while each SKU, size, link, and offer describe one variant. If the large hoodie is sold out, its link should open Large and its offer should carry OutOfStock.

Open both links and confirm that the selected size changes. Then search the markup for each SKU and verify that it appears once. Duplicate SKUs erase the distinction the group is meant to preserve, even when the names look different.

Stores that put each color on a separate page need the multi-page shape covered in the FAQ. The wider URL decision belongs to product page SEO.

4. Set each variant's stock state

Keep restocking variants OutOfStock, remove permanent delistings, and use Discontinued on live pages. Google supports both values. This three-way choice is my recommendation because its documentation doesn't prescribe when to use each one.

Your import-app setting decides which result reaches the store. DSers documents Remove variant, Set quantity to zero on store, and Do nothing. AutoDS moves an unavailable product to out of stock at its next monitoring scan. Theme-generated markup should follow the resulting product record, but confirm that expectation in the page source after a test change.

Map each supplier event to one store result:

Supplier eventImport-app actionStore and markup resultAvailability value
Sold out, expected backSet quantity to zeroVariant remains but can't be boughtOutOfStock
Delisted for goodRemove variantVariant leaves the product and markupNone
Delisted, page stays liveKeep variant and close salesVariant remains as endedDiscontinued
Stock changes, app does nothingDo nothingOld state may remain visibleUnreliable until fixed

Imagine the supplier drops the XL hoodie. Zero quantity keeps XL selectable and marks it out of stock. Removing the variant makes it disappear from the product and its markup.

After either change, reopen the page source and search for the XL SKU. This second check proves whether the theme followed the Shopify record or kept stale markup in a separate app block. A Do nothing setting fails the sequence because it preserves an old state instead of choosing one.

The page-level choice to keep, redirect, or remove an entire product is separate. Use the decision in out-of-stock product SEO for that page.

5. Match the feed, then validate

Use one group identifier for productGroupID in the markup and item_group_id in the feed. Merchant Center maps that field to Product.inProductGroupWithID and ProductGroup.productGroupId. Every variant in one group shares the feed value.

This check joins two records of the same product. Your product feed sends its variant group outside the page.

Google Merchant Center receives that group, while the page markup names it in schema.org's productGroupID form. A feed app that invents a different value gives Google two identifiers for the same variants.

Compare them in this order:

  1. Read item_group_id for one product in the feed.
  2. Read productGroupID for that product in the page source.
  3. Fix the feed app or markup source until the values match.
  4. Run Google's Rich Results Test before publishing.

Save the product ID, feed value, and markup value in your audit notes. If the app changes its group key after a reimport, that record shows where to investigate. After a feed-app migration or theme change, recheck one live product because either system can rewrite its value.

Merchant Center documents the property mapping. Google's variant guide is silent on any matching requirement between systems, which limits the claim. Your app also decides the exact feed value. Checking both records in your store is the only reliable answer.

When ProductGroup markup can't help

ProductGroup markup describes the variants your store holds, but it can't correct a wrong option, missing variant, or stale stock record. Google also doesn't guarantee that a feature using structured data will appear in search results.

The fix belongs where the bad state entered the chain. Change the import-app setting, let the sync update Shopify, and inspect the page source again. More markup only repeats a record that's still wrong.

The sequence is done when the source contains one product block and every supported option maps cleanly. Each variant also needs its own ID and link, while the stock states must match Shopify. The feed and page must share a group identifier.

Save the Rich Results Test result, then repeat the source review after the next supplier stock change.

If a test fails, roll back the newest custom block instead of editing several sources at once. Keep the theme output running, fix the store record or the single app that owns the markup, and test again. That path preserves a known baseline while you isolate the bad source.

No measured traffic effect with a disclosed sample supports a promise here. Start with a best seller whose URL will last. I recommend using the durable-page sequence in SEO for dropshipping before marking up products likely to disappear.

FAQ

What if each color is its own product?

Use isVariantOf on each variant page to point back to the shared ProductGroup, and keep the same group ID across those pages. Repeat the group definition where needed, but don't use the ProductGroup url property for a multi-page setup.

Can reviews go on the ProductGroup?

Yes. A ProductGroup can carry shared brand and review information once for all variants. The review fields still need to follow Google's review-markup rules.

How do I know Google accepted the markup?

Use Search Console's rich result status reports after launch to monitor validity, since templates or serving changes can break markup later. A valid report confirms the implementation, not that Google will show a rich result.

Share article

Page Contents

Try Dropship

Discover winning product to sell today

Claim offer

Shopify Offer

Start and sell with Shopify $1/month for 3 months.

Claim offer
  • Seguimiento de ventas
  • Portafolio
  • Biblioteca de tiendas
  • Rastreador de anunciantes
  • Biblioteca de anuncios
  • Biblioteca de productos
  • Competidores
  • Biblioteca de anunciantes
  • Búsqueda mágica con IA
  • Biblioteca de creadores

Lanza hoy mismo tu próximo producto ganador

Encuentra tu próximo producto ganador con filtros inteligentes en millones de productos, tiendas y anuncios, adaptados a tu nicho.