The Shopify-specific duplicate pattern
Shopify routes every product at /products/handle and also at /collections/foo/products/handle whenever the product belongs to a collection. The platform auto-canonicals the collection-prefixed URL back to the canonical /products/handle, which means Google treats them as one resource — but only when the canonical tag is correctly emitted by the theme. Custom-coded theme templates, third-party page-builder apps, and stores using the within: collection Liquid filter without a canonical override are the cases where the auto-canonical fails.
What Shopify's auto-canonical actually does
Shopify's SEO overview states the platform auto-generates canonical tags 'to prevent duplicate content from appearing in search results.' The auto-canonical fires on products, collections, pages, and blog posts. It is self-referencing on the canonical URL (the page's canonical points to itself) and signal-bearing on duplicate URLs (the collection-prefixed product URL's canonical points to the /products/handle canonical URL). Per Google's canonicalization doc, this is the correct rel='canonical' pattern — Google reads it as a strong signal but reserves the right to choose a different canonical if other signals contradict.
Filtered collection URLs and the /collections/*+* pattern
Shopify collections support faceted filtering — colour, size, price, vendor, tag. Each filter combination produces a URL like /collections/dresses/red+xl. The combination pattern is open-ended: every filter combo creates a unique URL with thin, near-duplicate content. Shopify's default robots.txt blocks /collections/*+* (the wildcard pattern matches any filter URL with two or more values) to suppress this duplicate URL surface from Google's crawl. Unblocking this is almost never the right move.
/search is blocked by default — and that's correct
Shopify's default robots.txt blocks /search (the internal search results URL). Internal search results pages are inherently thin-content — they render a query string ('blue dress') against a product list with no editorial content, no unique meta, and no canonical product. Google has long downgraded sites that allow internal search pages to compete with editorial pages. Leaving /search blocked is the correct default.
When the auto-canonical fails
Three failure modes account for most Shopify canonical issues: (1) custom-coded theme templates that lost the canonical_url Liquid object during a redesign; (2) third-party page-builder apps (PageFly, Shogun, GemPages) that re-render the page head and skip the auto-canonical; (3) stores using the within: collection Liquid filter to render collection-aware product templates without a canonical override. Each failure mode produces a different GSC signature.