Shopify · Collections, variants and filters
Most alternate Shopify product URLs are normal platform behavior, not errors. The problem starts when the rendered canonical tag, the theme's internal links and the store's crawl paths send Google conflicting signals about which URL is the real one.
Generic duplicate content advice stops at "add a canonical tag." On Shopify, the canonical tag is usually already there. What breaks is everything around it. This page audits each URL pattern at the URL level: request it, inspect its HTTP status, canonical target, indexability and inlinks, find the theme or app that generates it, fix the source, then recrawl and compare.
Quick answer: Shopify canonicalizes /collections/{collection}/products/{handle} and ?variant= URLs to /products/{handle} by default. Confirm the rendered canonical still points there after theme and app changes, stop the theme linking to collection-aware product paths where possible, and decide case by case whether /collections/all and tag-filtered collections deserve indexing.
How Shopify creates multiple URLs for the same product
Shopify routes products by handle, so any template that can render a product can produce a new URL for it. Using one hypothetical product, a Classic Shirt in the Menswear collection:
One product, many paths: each URL form needs its own validation
Different URL forms require different validation. Not every alternate URL is an error.
| URL pattern | What it is | What to inspect |
|---|---|---|
| /products/classic-shirt | Primary product URL | Status, canonical, indexability |
| /collections/menswear/products/classic-shirt | Collection-aware product path | Canonical destination, which links generate it |
| /products/classic-shirt?variant=123456789 | Preselected variant | Variant selection, canonical, search intent |
| /collections/all | Automatic all-products listing | Route availability, purpose, indexability, inlinks |
| /collections/menswear/red | Tag-filtered collection | Filter behavior, canonical, search value |
| /collections/menswear/red+cotton | Combined tag filter | URL proliferation, robots.txt rules |
These are illustrative patterns. Confirm the actual response codes and canonical output on the store you are auditing.
Product URLs versus collection-based product URLs
When a theme renders a product card inside a collection template, it often builds the link with the Liquid filter within: collection. The collection-aware path exists so breadcrumbs and next-product navigation know which collection the shopper came from. A product in eight collections can have eight alternate URLs plus the canonical one.
Variant parameters and product selection
A ?variant= parameter tells the product template which size, color or material to preselect. Themes write it to the address bar when a shopper changes an option, and Google Merchant Center feeds often link to it directly. Each variant ID creates a distinct URL serving nearly identical HTML.
Collection filters, tags and alternate paths
Legacy tag filtering appends tag handles to the collection path. Storefront filtering through the Search & Discovery app uses query parameters such as ?filter.v.option.color=red and ?filter.v.price.gte=20. Add sort_by and page parameters and one collection can expose hundreds of crawlable combinations.
Why different URLs do not automatically mean duplicate indexable pages
A duplicate URL becomes a ranking problem only when Google crawls it often, selects it as canonical, or splits link equity across versions. Crawl discovery, canonical selection, indexability and index status are four separate conditions. Diagnose which one is failing before changing anything.
Audit Shopify collection-based product URLs
Every collection-aware product path should return 200, render a canonical pointing to /products/{handle}, and receive as few internal links as your theme allows.
Compare /products/product-handle with /collections/collection-handle/products/product-handle
Request both URLs and compare the rendered HTML, not the Liquid source. The title tag, H1, description, price and Product and Offer structured data should match. If the collection path shows different content, an app or custom section is injecting collection-specific blocks.
Check canonical targets on both URL versions
Both versions should output the absolute https URL of /products/classic-shirt on your primary domain. Watch for these failure modes:
- The canonical points to the collection path itself, usually because a theme hardcoded request.path instead of canonical_url.
- The canonical uses the myshopify.com domain or a non-primary market domain.
- Two canonical tags appear, one from the theme and one from an SEO app.
- The canonical target returns a redirect or 404 after a handle change.
Find internal links that generate collection-based product paths
Crawl the store and filter inlinks by URL pattern. In most themes the sources are the product card snippet (card-product.liquid or product-grid-item.liquid), the collection template and search results. Search the theme code for within: collection and within: current_collection.
Verify product cards, breadcrumbs and related-product links
Check each link source separately: collection product cards, breadcrumb trails, recommended products and complete-the-look sections, and mega menu product links. Many stores fix the product card and forget related-product blocks or a quick-view app, which keeps feeding crawlers the alternate path.
Check Shopify variant URLs and ?variant= parameters
In a default Shopify setup, every ?variant= URL canonicalizes to the parent product. That is correct for most catalogs, but verify it rather than assume it.
How variant URLs differ from the main product URL
The HTML differs only in the preselected option, the displayed price or inventory status, and sometimes the featured image. Title tag, H1 and description usually stay the same, which is why Google treats these as duplicates of the parent product.
Validate canonical tags on variant URLs
Pull three or four variant IDs from the product JSON (append .json or .js to the product URL) and request each. The canonical should strip the parameter. If a custom theme builds the canonical from the full request URL, every variant becomes self-canonical and indexable duplicates multiply across the catalog.
Check whether variant selection preserves the correct product experience
Load each variant URL with JavaScript enabled. Confirm the correct option is selected, price and availability match, and add to cart adds that variant. Merchant Center and Shopping ads land shoppers on these URLs, and a feed price that does not match the page price can trigger item disapprovals.
Identify when variants require distinct search landing pages
Some variants carry their own search demand: a color people search by name, a size category such as wide fit, or a material that changes the product. If demand exists, split the variant into a separate product with its own handle. Canonical tags cannot make a parameter URL a strong standalone landing page.
Avoid redirects that break variant selection or discard useful functionality
Do not 301 redirect ?variant= URLs to the bare product URL. That strips the selection, breaks feed and ad landing pages, and frustrates shoppers who share a specific color. Leave the parameter working and let the canonical tag handle consolidation.
Audit /collections/all and overlapping collections
Every Shopify store has /collections/all, even if you never created it. It lists every published product, paginates through ?page= URLs, and often has no unique title, description or purpose.
Check whether the all-products collection is active
Request /collections/all and note the status code, title tag and product count. A manual collection with the handle "all" overrides the automatic one, so check Products > Collections in the admin first.
Compare its product listings with curated collections
On small catalogs, /collections/all may list the same products as /collections/shop or the homepage product grid. Two listing pages with near-identical product sets and thin copy compete for the same generic brand catalog queries.
Inspect internal links, canonical tags and indexability
Find which templates link to it (Shop all buttons, default footer menus and empty-cart pages are common), whether its paginated pages self-canonicalize, and whether it appears in sitemap.xml. Then use URL Inspection in Google Search Console to see the canonical Google selected.
Decide whether to retain, improve, redirect or exclude a route
| Situation | Recommended action |
|---|---|
| It ranks and earns traffic for brand catalog queries | Keep it, add a unique title, meta description and intro copy |
| A curated Shop all collection does the same job better | 301 redirect /collections/all in URL Redirects |
| It is linked internally but adds no search value | Add a noindex meta tag through a template condition, keep it crawlable |
| Nothing links to it and Google ignores it | Leave it alone and monitor |
Find duplicate or low-value tag-filtered collection URLs
Tag filters are where Shopify crawl paths multiply fastest. A collection with 10 tags can expose 10 single-tag URLs and dozens of combinations, each self-canonical in many themes.
Identify tag-based collection paths
Filter crawled collection URLs with a third path segment, such as /collections/menswear/red. Also capture Search & Discovery parameters (filter.v.option, filter.p.product_type, filter.v.price) and sort_by values.
Check multiple tags and combinations that expand URL variants
Combined tags use a plus sign. Shopify's default robots.txt disallows /collections/*+* and /collections/*%2B*, plus sort_by parameters. If robots.txt.liquid was customized, confirm those rules still exist. Disallowed URLs can still be indexed without content if they receive many links.
Distinguish useful category landing pages from navigation-only filters
Some single-tag pages match real queries, such as red linen shirts or vegan leather boots. Those deserve dedicated collections with their own handle, title tag, H1 and intro copy. Filters like size M, in stock or under $50 are navigation aids with little standalone demand.
Validate canonical, robots directives and internal link discovery
For each filter URL type, record whether the canonical points to itself or the parent collection, whether meta robots noindex is present, whether robots.txt blocks it, and how many internal links point to it. Filter sidebars rendered as plain <a href> links are the main discovery source.
Control unnecessary filter combinations without blocking valuable pages
Promote high-value tag pages to real collections and link them from navigation. For the rest, keep the default robots.txt rules and add noindex to filtered views through a Liquid condition on current_tags. Never canonicalize a filtered page to the parent while also blocking it in robots.txt: Google cannot read a canonical on a URL it may not crawl.
Fix Shopify duplicate URL problems without breaking the store
Fix the source of the alternate URL first, then the signal, and only redirect or noindex when the URL has no purpose.
Correct theme-generated product links
In the product card snippet, replace the collection-aware link with the plain product URL. Repeat for related products, search results and any section that renders product links. Make the change on a duplicate theme and test breadcrumbs before publishing.
{%- # Before -%}
<a href="{{ product.url | within: collection }}">
{%- # After -%}
<a href="{{ product.url }}">
Preserve or correct canonical output
The head in layout/theme.liquid should contain exactly one canonical tag built from Shopify's canonical_url object. Remove duplicates added by SEO apps or old custom code.
<link rel="canonical" href="{{ canonical_url }}">
Use redirects only when URLs should permanently resolve elsewhere
Use 301 redirects in Online Store > Navigation > URL Redirects for changed product handles, merged products, retired collections, and /collections/all when a curated collection replaces it. Do not redirect collection-aware product paths or variant URLs.
Apply noindex selectively where appropriate
Noindex fits thin filtered views, internal search results and redundant listing pages. Keep these pages crawlable so Google can see the directive.
{%- if template contains 'collection' and current_tags -%}
<meta name="robots" content="noindex, follow">
{%- endif -%}
Avoid conflicting canonical, redirect and robots directives
- A canonical pointing to a URL that redirects or returns 404.
- A noindex page that is also the canonical target of other pages.
- A robots.txt block on a URL whose noindex or canonical you want Google to read.
- A page listed in sitemap.xml while canonicalized elsewhere.
Validate Shopify URL fixes after theme or app changes
Duplicate URL problems usually return through a theme update, a new app or a navigation edit. Treat validation as a repeatable workflow:
- Collect URL patterns. Group crawled URLs into products, collection-based product paths, variants, all-products routes and filtered collections.
- Inspect technical signals. Record HTTP status, canonical destination, indexability and internal inlinks for each group.
- Identify the source. Determine whether the pattern comes from theme links, collection navigation, filters, apps or custom code.
- Correct the underlying issue. Choose the fix based on the intended behavior of that URL type.
- Recrawl and compare. Confirm the change fixed the target URLs and introduced no new regressions.
Crawl representative product and collection URL patterns
You do not need to crawl 20,000 variant URLs. Build a test set of 10 to 20 URLs per pattern: products in many collections, products with many variants, large collections and your busiest filter combinations.
Compare HTTP status, canonical target, indexability and internal links
Record the four signals per URL in your baseline and after every change. The pattern view matters most: if inlinks to /collections/*/products/* jump from 0 to 4,000 after an update, one snippet changed.
Inlinks to /collections/*/products/*: 0
Self-canonical product URLs: 412 / 412
Inlinks to /collections/*/products/*: 16,135
Self-canonical product URLs: 412 / 412
Test variant selection and filtered collection behavior
Crawlers do not click option selectors, so test these manually or with a headless browser. Confirm variant URLs still preselect correctly and filters still return the right products.
Compare the latest crawl with the previous baseline
| Finding | Recommended investigation |
|---|---|
| Alternate product path returns 200 | Inspect canonical and rendered page content |
| Canonical points to the wrong product | Check theme Liquid, custom SEO code and app modifications |
| Canonical is correct but alternate links are widespread | Fix the source of internal links where practical |
| Variant URL loses the selected variant | Test the product form, URL handling and theme JavaScript before changing URL behavior |
| Filter combinations generate many URLs | Evaluate crawl discovery, page value, internal linking and indexation controls |
| A canonical target redirects or returns an error | Correct the canonical destination and verify the target response |
Prioritize regressions affecting many products or collections
A broken canonical in the product template affects every product; a stray link in one blog post affects one URL. Fix template-level regressions first, then confirm in the Search Console Page indexing report that "Duplicate, Google chose different canonical than user" counts fall over the following weeks. For update-specific regressions such as changed metadata and leftover app scripts, see Shopify SEO after a theme update.
Downloadable checklist
Tick items as you audit, then download the list as CSV for a spreadsheet or ticket, or print it and save as PDF. Your ticks and the corrective action for each check are included in the download.
Frequently asked questions
Are Shopify collection product URLs duplicates?
Yes, technically. /collections/menswear/products/classic-shirt serves the same content as /products/classic-shirt. Shopify canonicalizes it to the product URL by default, so it is rarely an indexing problem. The real cost is crawl efficiency and diluted internal linking when the theme links to the collection path everywhere.
Should Shopify variant URLs be canonicalized to the main product?
In most cases, yes. Variants share a title, description and intent with the parent product. If a variant has its own search demand and unique content, make it a separate product with its own handle instead of indexing a parameter URL.
Should /collections/all be indexed?
Only if it serves a purpose a curated collection does not. If it ranks for brand catalog queries, give it unique copy. If a Shop all collection already covers it, redirect it or noindex it.
Should filtered Shopify collection URLs be noindexed?
Navigation-only filters such as size, availability and price ranges usually should be. Filters that match real search queries, such as a color plus product type, are better turned into dedicated collections than left as filter URLs.
Do canonical tags prevent Google from crawling alternate URLs?
No. A canonical tag is a hint about which URL to index, not a crawl directive. Google still crawls linked alternate URLs and may ignore the canonical if internal links, sitemaps and content point elsewhere.
How can I find Shopify duplicate URLs after a theme update?
Crawl a representative URL set before publishing the new theme, crawl it again after, and compare status codes, canonical targets, indexability and inlink counts by URL pattern. Then check the Search Console Page indexing report for growth in duplicate canonical exclusions.