Shopify duplicate content is mostly a plumbing problem, not a penalty problem. The platform generates several URLs for the same product or collection by design, and out of the box it canonicalises most of them correctly. The ones it does not handle are tag pages, /collections/all, and the meta descriptions your theme invents when a product or collection has none. Those three are where the actual damage sits, and each needs a different fix β a canonical tag, a noindex, or a rewrite. One generic "add a canonical tag" tip will not clear it.
Below is the full map of what Shopify duplicates by default, with the specific fix for each.
Every duplicate URL Shopify creates without you asking
Open your own store and you will find the same product reachable at several addresses:
- /products/handle β the canonical product URL.
- /collections/collection-handle/products/handle β the same product, scoped to whichever collection the shopper clicked in from. One per collection the product belongs to.
- /products/handle?variant=41234567890 β a variant deep link, produced by your own variant picker and by Google Shopping feeds.
- /collections/all β every published product in one paginated list, overlapping heavily with your real collections.
- /collections/collection-handle/tag-name β a tag-filtered view of a collection. Multiply by every tag on every product.
- ?page=2, ?page=3 β pagination on collections, blogs and the vendor and type pages.
- ?sort_by=price-ascending and friends β the same products in a different order.
- ?filter.v.option.colour=black β Search & Discovery filter parameters, in any combination.
- your-store.myshopify.com β a full second copy of the storefront on the permanent domain.
Some arithmetic, because the scale is what makes this worth an afternoon. Take a catalogue of 1,200 products across 40 collections, with each product sitting in an average of three collections. That is 1,200 canonical product URLs plus 3,600 collection-scoped copies: 4,800 crawlable product paths. Give each collection six tags and you add 240 tag pages. Paginate /collections/all at 24 products a page and that is another 50 URLs. Your sitemap says 1,200 products. Googlebot is looking at more than 5,000 doors.
Does Shopify duplicate content hurt SEO?
There is no duplicate content penalty. Google has said this for years and it remains true. What duplicate URLs actually cost you is more mundane and more annoying to unpick.
First, crawl waste. On a 200-product store nobody cares. On a 5,000-SKU catalogue with tag pages and filters live, Googlebot spends its budget on near-identical lists instead of your new arrivals, and new products take days longer to appear.
Second, Google can choose a canonical you did not intend. In Search Console this shows up as Duplicate, Google chose different canonical than user. We see it most often where a collection-scoped product URL picked up internal links from a homepage carousel and the bare /products/ URL did not.
Third, split signals. Two versions of the same collection each earning a handful of links means neither ranks as well as one version earning all of them.
And fourth, the one founders actually notice: a tag page ranking for the query the collection page should own, with a thinner product set and a meta description that reads like a template.
Collection-scoped product URLs and the Shopify canonical tag setup
Shopify's theme layout includes a canonical link built from the canonical_url object. On /collections/shirts/products/oxford-shirt that object outputs /products/oxford-shirt. So the collection-scoped copies are already consolidated, and so are the ?variant= links and the ?sort_by= variations.
Two things break it.
One, a theme edit that removed the canonical line. It happens more than you would expect β usually during a head cleanup for speed, or when a developer replaced the SEO block with a hardcoded tag. Check by loading a collection-scoped product URL and searching the page source for rel="canonical". If it points at the URL you are on rather than /products/, that is your bug.
Two, an app or a custom section that injects a second canonical tag. Two canonicals in one head means Google ignores both. Search the source for the string twice.
If you would rather stop generating the collection-scoped paths at all, change your product links in the theme to use the product's bare URL instead of within: collection. The trade-off is real: you lose the collection breadcrumb context and the previous/next product navigation inside a collection. On most stores that is a fair swap. On a store where shoppers browse deep inside one collection, it is not.
The /collections/all page: keep it, but stop it competing
Shopify creates /collections/all for every store and there is no setting to turn it off. It has a self-referencing canonical, so Google is free to index it, and on stores with a broad catalogue it often does β then ranks it for a brand-plus-category query where a curated collection would convert better.
Our default: leave the page live for crawl paths and internal utility, but give it a noindex. In your theme layout, wrap a robots meta tag in a check for the collection handle:
{% if collection.handle == 'all' %}<meta name="robots" content="noindex, follow">{% endif %}
Keep follow. You still want link equity flowing through to products. Do not block it in robots.txt instead β a blocked URL cannot be crawled, so Google never reads the noindex and any version already indexed stays indexed.
The exception: single-category stores with fewer than about 150 SKUs, where /collections/all genuinely is the shop page and gets linked in the main nav. Then index it, write a proper description for it, and noindex the near-duplicate "Shop All" collection you built by hand.
Tag pages: noindex nearly all of them
Tag-filtered collection URLs are the biggest single source of thin duplicates on Indian D2C stores, because tags get used for merchandising rather than navigation β sale, new, festive, gifting-under-999, plus size, colour, fabric. Each combination is a crawlable URL with the collection's own copy at the top and a subset of its products below.
Shopify's default robots.txt already disallows multi-tag combination URLs (the ones with a plus sign) and the sort_by parameter. Load your own /robots.txt and read it. Single-tag pages are not covered.
The fix is a conditional noindex in the theme head:
{% if current_tags %}<meta name="robots" content="noindex, follow">{% endif %}
Then make the deliberate exceptions. If /collections/sarees/silk gets real search demand and you have written unique copy for it, promote it to a proper collection with its own handle, its own meta title and its own content, and link it from the nav. A tag page you actually want to rank should not be a tag page.
Blog tags behave the same way, at /blogs/news/tagged/tag-name. Same treatment.
Shopify pagination SEO: page 2 is not a duplicate
Google retired rel="next" and rel="prev" as an indexing signal years ago, so do not spend a developer hour adding them. What matters now is simpler.
Confirm that ?page=2 carries a self-referencing canonical, not one pointing back to page 1. Canonicalising every paginated page to page 1 is the classic mistake, and it tells Google that the products on pages 2 through 40 do not exist as far as discovery is concerned. Shopify's canonical_url retains the page parameter, so a stock theme is fine. Themes that build the canonical manually from shop.url plus a handle are not.
Keep paginated pages indexable and let Google use them as crawl paths. If your collections run past 15 or 20 pages, the more useful change is reducing how deep the pagination goes β larger page sizes, or better filtering so shoppers never need page 12. Infinite scroll with no crawlable links underneath is the worst of both: shoppers cannot deep link and Googlebot cannot follow.
Filters, sort and search parameters
Search & Discovery filter URLs are query-parameter based, and Shopify canonicalises them back to the bare collection. Verify it on your store rather than trusting it, because third-party filter apps sometimes generate path-based filter URLs instead, and those get indexed.
Two rules we apply on catalogues large enough to need faceted navigation. Filter combinations should not be linked in a crawlable way from anywhere except the filter UI itself. And any filter view you want indexed β colour, occasion, price band with real demand behind it β becomes a real collection with real copy, not a parameter.
If your filters are the reason shoppers bounce off page 1 of a collection, that is a merchandising fix rather than an SEO one. Our FilterPro app handles the filter and on-site search side without adding path-based URLs to the crawl. Search results pages themselves are already disallowed in Shopify's default robots.txt.
How to fix duplicate meta descriptions on Shopify
This is the one that has nothing to do with URLs and costs the most impressions. Most themes fall back to shop.description when a product or collection has no meta description of its own. So 900 products share one sentence, and Search Console's HTML improvements go quiet while Google rewrites your snippets from whatever text it can find on the page.
Three steps, in order.
- Change the fallback in the theme so an empty meta description outputs nothing at all. An absent description lets Google generate a snippet from page content, which beats a repeated one every time.
- Write descriptions by hand for your top 100 URLs by revenue and by impressions. Not top 100 by traffic β by revenue, because that is where a better snippet pays.
- For the long tail, template with real variables: product type, key material or ingredient, price band, shipping or COD availability. A templated description with three distinct variables is not a duplicate. One with only the product title in it is.
Same principle for titles. If 400 of your title tags are the product name plus your brand name, you have not written titles, you have concatenated fields. Our SEO and content work usually starts here because it is the fastest measurable win on a store that has never had the head tags looked at.
The 40-minute audit
Do this yourself before you brief anyone.
- Load a product from inside a collection and check the canonical resolves to /products/.
- Search the page source for rel="canonical" and count. One, not two.
- In Google, run a site: query restricted to your domain and the string /collections/all. Anything indexed?
- Same for a tag path you know exists.
- Search Console, Pages report, open Duplicate, Google chose different canonical than user and read 20 examples. The pattern will be obvious within five.
- Compare your sitemap product count against total indexed pages. A gap of 3x or more means parameter and tag URLs are eating crawl.
- Check your-store.myshopify.com in a browser. It should carry canonicals to your live domain.
If steps one and two pass and step five is empty, you do not have a duplicate content problem and you should go spend the time on page speed or product copy instead.
If they do not pass, the fixes above are theme-level edits β an hour of work for someone who has done them before, half a day for someone learning on your live store. Take a theme backup first, and put the changes through a duplicate theme with a preview URL, not the published one. If you would rather not touch Liquid yourself, we run this as part of a store audit, or you can bring in a Shopify developer for the theme work directly.


