/ โ† Ecommerce Crawl Fixes / Product Variant URLs
In this guide
  1. The two models, and the muddle in between
  2. How to choose, product type by product type
  3. What makes a good variant URL
  4. Describing variants with ProductGroup
  5. Stopping variants from multiplying the crawl
  6. The fix, step by step
  7. Platform notes
  8. Questions and answers

The two models, and the muddle in between

There are two coherent ways to handle variants. Both are acceptable to search engines; problems start when a shop mixes them without meaning to.

Single pageSeparate pages
What it looks like/products/field-jacket, with ?colour=olive&size=m preselecting options/products/field-jacket-olive and /products/field-jacket-navy, each a full page
CanonicalEvery variant URL points to the base product URLEach page points to itself
What ranksOne page for the product as a wholeEach variant can rank for its own searches
Content effortOne description, shared reviewsDistinct images and at least some distinct text per page
Best forSizes, pack quantities, minor optionsColours or materials people search for by name, where images and stock differ

The muddle looks like this: a single product page whose colour swatches link to URLs that each canonicalise to themselves, but with identical titles and descriptions; or separate colour pages that all canonicalise to the first colour, so only one can ever be shown. The Ecommerce Crawl surfaces these as duplicate product URLs or as clusters of near-identical pages.

Variants are not the same issue as one product reachable through several paths, such as through different collections. That is covered in Fixing duplicate product URLs.

How to choose, product type by product type

You do not have to use one model across the whole shop. The right choice depends on how people search and how different the variants really are. Ask four questions for each product type:

  1. Do people search for the variant by name? "Navy linen shirt" is a real search; "linen shirt size 42" rarely is. Search Console queries and keyword tools show which attributes appear in searches.
  2. Does the variant look different? Different colours need different photos. Different sizes usually look identical.
  3. Can you write something distinct for it? If the only difference on a separate page would be one word in the title, the pages will be treated as duplicates.
  4. Does the variant have its own stock, price or identifiers? Separate GTINs and prices are normal for both models, but strongly different prices and availability make separate pages easier to understand.

A common and sensible result: colours on separate pages for clothing and furniture, where colour drives searches and photos; sizes, capacities and pack quantities as options on the same page. Accessories such as phone cases may justify separate pages by device model, because people search by model.

๐Ÿ’ก If you are unsure, start with the single-page model. Consolidating signals on one strong page is safer than splitting a product into thin pages, and it is easier to split later than to merge.

What makes a good variant URL

Whatever the model, each variant should be reachable at a URL that loads with that variant already selected. Google's product variant documentation asks for exactly this: a distinct URL per variant, for example using query parameters, that preselects the variant. Shopping ads and free listings also link to variant-level URLs, so a shopper who clicked "olive, medium" lands on olive, medium rather than the default.

Describing variants with ProductGroup

Google supports ProductGroup markup for variants. The group carries the shared details and lists each variant as a Product through hasVariant. variesBy names the attributes that differ, using schema.org properties such as https://schema.org/color and https://schema.org/size, and productGroupID ties the variants together. On a single-page setup the group's url is the base product URL. Full detail on offers, shipping and returns is in the Schema Builder guide; this is the variant-specific shape.

<script type="application/ld+json">
{
  "@context": "https://schema.org",
  "@type": "ProductGroup",
  "name": "Waxed field jacket",
  "description": "Waxed cotton field jacket with a corduroy collar and four front pockets.",
  "url": "https://www.example.co.uk/products/field-jacket",
  "brand": { "@type": "Brand", "name": "Hollowmere" },
  "productGroupID": "FJ100",
  "variesBy": ["https://schema.org/color", "https://schema.org/size"],
  "hasVariant": [
    {
      "@type": "Product",
      "sku": "FJ100-OLV-M",
      "gtin13": "5098765432109",
      "name": "Waxed field jacket, olive, medium",
      "image": "https://www.example.co.uk/images/fj100-olive.jpg",
      "color": "Olive",
      "size": "M",
      "offers": {
        "@type": "Offer",
        "url": "https://www.example.co.uk/products/field-jacket?colour=olive&size=m",
        "price": "149.00",
        "priceCurrency": "GBP",
        "availability": "https://schema.org/InStock"
      }
    },
    {
      "@type": "Product",
      "sku": "FJ100-NVY-M",
      "gtin13": "5098765432116",
      "name": "Waxed field jacket, navy, medium",
      "image": "https://www.example.co.uk/images/fj100-navy.jpg",
      "color": "Navy",
      "size": "M",
      "offers": {
        "@type": "Offer",
        "url": "https://www.example.co.uk/products/field-jacket?colour=navy&size=m",
        "price": "149.00",
        "priceCurrency": "GBP",
        "availability": "https://schema.org/OutOfStock"
      }
    }
  ]
}
</script>

On a separate-pages setup, each page describes its own variant as a Product and uses inProductGroupWithID to point at the shared group ID, with the group details repeated on each page or placed on one page and referenced. Only mark up variants that are actually offered on the page.

Stopping variants from multiplying the crawl

Variants can create a small explosion of their own. A jacket in six colours and seven sizes has 42 combinations, and if every swatch and size button is an ordinary link with its own parameters, crawlers will request all of them, plus every ordering of the parameters if the shop accepts both.

โš ๏ธ Changing the variant model on an established shop changes many URLs at once. Plan redirects from any URLs that disappear, update internal links and feeds in the same release, and do it outside your busiest season.

The fix, step by step

Step 1

List how variants currently appear as URLs

Pick five representative products of different types and click through every option on each, noting the URL, the canonical tag in the page source and the title each variant shows. Then run the Ecommerce Crawl and filter for product URLs with parameters or colour words in the path. You are looking for whether variants have their own URLs, whether they canonicalise consistently, and whether swatches are generating crawlable links to every combination.

Step 2

Choose one page or separate pages for each product type

For each product type, check whether people search for the variant by name, whether it looks different, whether you can write distinct content for it, and whether stock and price differ. Use Search Console queries to see which attributes appear in real searches. Write the decision down as a short rule, such as colours on separate pages and sizes as options, so product managers apply it the same way to every new listing.

Step 3

Give every variant a stable, preselecting URL

Make sure each variant loads at its own URL with the right options already selected, showing the correct image, price and stock in the page as delivered. Use readable parameters or the platform variant ID, output options in one fixed order, and make sure the URL does not change when products are re-imported. Test by pasting a variant URL into a private browser window and checking that the page opens on that exact variant.

Step 4

Set canonicals to match the model

On the single-page model, every variant URL should carry a canonical tag pointing to the base product URL without parameters. On the separate-pages model, each variant page should carry a self-referencing canonical and never point to a sibling colour. Check a sample in the page source and in the URL Inspection tool in Search Console, which shows the canonical Google selected, and correct any template that outputs a different canonical from the one you intended.

Step 5

Control how swatches and option links are crawled

Decide which options need crawlable links. On a single page, sizes and minor options can be buttons or form controls that update the page without an <a href>. On separate pages, colour swatches should link to the sibling colour pages using their clean URLs, while size choices stay inside each page. Remove any template code that adds variant parameters to links in category listings unless you deliberately want that variant shown first.

Step 6

Mark up the product group and its variants

Add ProductGroup markup with name, productGroupID, variesBy and a hasVariant list, giving each variant its own sku, identifiers, image, attributes and an offer whose URL is the preselecting variant URL. On separate pages, use inProductGroupWithID on each variant. Remove older markup that describes only the default variant, and test the page in the Rich Results Test to confirm the variants are detected.

Step 7

Align sitemaps and shopping feeds

Your XML sitemap should list only canonical URLs: the base product on the single-page model, each variant page on the separate-pages model. Your shopping feed, by contrast, usually lists one row per purchasable variant with its preselecting URL, sharing an item group ID that matches your productGroupID. Check that the price and availability in the feed, the markup and the visible page agree for a sample of variants.

Step 8

Test variant URLs and recrawl

Run the Ecommerce Crawl again and check that variant URLs are no longer reported as competing duplicates, and that the number of crawlable variant combinations has dropped where you removed links. Inspect a few variant URLs in Search Console to confirm the Google-selected canonical matches yours. Keep an eye on the Page indexing report over the following weeks for variant URLs moving into the alternate page with proper canonical tag status.

Platform notes

Shopify

Shopify uses the single-page model by default. Each variant is reachable at /products/handle?variant= followed by a numeric ID, and themes output a canonical to the plain product URL. Shopify allows a limited number of options and variants per product, so large ranges are sometimes split into separate products by colour, which moves you into the separate-pages model; if you do that, link sibling colours to each other and give each its own photos and text.

WooCommerce

Variable products keep variants on one page, with attributes selectable by dropdown. Out of the box, variations do not get their own preselecting URLs unless attributes are passed as ?attribute_pa_colour= parameters, which WooCommerce can read. Check that your theme keeps the canonical on the parent product when those parameters are present.

Custom builds

Design the variant URL scheme deliberately before launch: readable parameters for the single-page model, or a clean path segment per variant for separate pages. Render the selected variant's details on the server so crawlers see the right image and price.

Questions and answers

1. Should each colour of a product have its own page?

Only when colour affects how people search and what they see. If shoppers search for navy linen shirt or oak dining table, and each colour has its own photos, separate pages can rank for those searches. If the colours differ only by one word and share the same photos and text, separate pages will look like duplicates, and one page with selectable options is the better choice. You can use different models for different product types in the same shop.

2. Should variant URLs have a canonical pointing to the main product?

On the single-page model, yes: every variant URL, such as one with a variant or colour parameter, should point its canonical to the base product URL, so signals consolidate on one page. On the separate-pages model, no: each variant page should point to itself, because the pages are meant to rank separately. The error to avoid is pointing all separate colour pages to one of them, which stops the others from ever appearing in results.

3. Do product variants cause duplicate content penalties?

There is no penalty for having variants. The practical risk is that Google sees several near-identical pages, picks one as canonical itself, and ignores the rest, which may not be the one you would have chosen. It also spends crawl on pages that add nothing new. Clear canonicals, a deliberate choice between the two models, and distinct content on any separate variant pages keep Google choosing the pages you intended.

4. Is ProductGroup markup required for variants?

No, it is optional. Product markup on its own still works, but it only describes one variant at a time, and search engines have to work out the relationship between variants themselves. ProductGroup with hasVariant, variesBy and productGroupID states the relationship explicitly, and Google documents it for exactly this purpose. It is most useful for shops with many variants per product, and for anyone also running shopping feeds, where the group ID can match the feed's item group.

5. Should I block variant parameters in robots.txt?

Usually not. Google needs to fetch variant URLs to read their canonical tags, and free listings and shopping ads often send shoppers to variant URLs, which Google checks for price and availability. Blocking them can cause feed and landing page problems. A better way to reduce variant crawling is to stop generating crawlable links to every combination, for example by using buttons for sizes, while leaving the URLs themselves working and canonicalised.

6. What happens to rankings if I switch variant models?

Expect some movement while Google processes the change. Moving from separate pages to one page means redirecting the retired variant URLs to the main product with the right option preselected, so any links and history carry across. Moving the other way means creating new pages that have no history yet. In both cases, update internal links, sitemaps and feeds in the same release, and avoid making the change just before your busiest season.

Check how your variant URLs are crawled

The Ecommerce Crawl maps the URLs on your store, finds faceted navigation explosion and duplicate product URLs, flags out-of-stock products, surfaces orphans and measures how efficiently your crawl is spent.

Open Ecommerce Crawl Fixes โ†’
๐Ÿ’ฌ Got a problem?
Related Guides: All Ecommerce Crawl Fixes  ·  Duplicate Product URLs  ·  Canonical Tag Problems  ·  Schema Builder Guide  ·  Learning Hub

About aiwebpageseo

aiwebpageseo.com is a data-driven SEO and AEO (Answer Engine Optimisation) platform providing a free suite of technical SEO tools. Rather than relying on AI-theorised assumptions, the platform analyses live URL performance, delivering objective diagnostics, page speed metrics, CLS debugging, and site crawl data alongside actionable technical tutorials.