Shopify Collection Page SEO: The URL Structure Problem Nobody Fixes
Why /collections/all and /collections/frontpage duplicate content kills ranking, and the canonical plus rewrite pattern we use. Includes the metaobject-driven landing pages we build for merchants...
Every Shopify store we audit has the same problem, and almost none of the owners know it exists. The platform ships with a URL architecture that actively fights your rankings. Products live at two addresses. Collections auto-generate behind your back. Tag filters mint fresh crawl paths every time someone adds an attribute. Canonical tags point to the wrong places by default on the two URL patterns that matter most. And the worst offender, a collection called /collections/all, sits quietly in your sitemap hoovering up crawl budget that should be flowing to your real category pages.
This article walks through exactly what breaks, why Shopify ships it this way, and the pattern we apply across the stores we maintain. We will also cover the metaobject-driven landing page approach that has replaced traditional collection pages for clients who actually want to rank for head-term category keywords.
The Duplicate URL Problem Shopify Ships by Default
Shopify gives every product two perfectly valid URLs. The first is clean and predictable, /products/some-handle. The second is the collection-contextualised version, /collections/some-collection/products/some-handle, which appears whenever a shopper clicks a product from within a collection grid. Both resolve, both return a 200, both render the full product template. Without intervention, Google can and will discover both, and for any store with a sensible internal linking structure, the contextualised version is the one most often crawled because it is the path the theme links to.
Shopify does handle this. Modern themes rendering the canonical_url Liquid object correctly will output a rel=canonical on the collection-contextualised page pointing back to the clean /products/ URL. The problem is that we have audited roughly 250 stores now and a meaningful chunk of them, especially those on forked or heavily customised themes, either fail to emit the canonical or emit one that self-references the longer path. If your theme was built before 2019, if a developer swapped canonical_url for a hardcoded request.path, if you are running a heavily modified Dawn variant, check the rendered HTML on a collection-contextualised product URL right now. You will often find the canonical is wrong.
Then there is /collections/all. Shopify creates this automatically the moment you publish a product. It lists every published SKU, paginated, with no curation and no editorial framing. For a store with a thousand products and a default 24 per page, that is forty-two paginated URLs of thin, unfocused content sitting in your sitemap. Googlebot crawls it. It appears in Search Console. It competes with your real, well-targeted collection pages for relevance signals. Most themes link to it from a "View all products" button on the homepage, which means it picks up internal link equity too. It is a crawl budget leak dressed up as a feature.
/collections/frontpage is the second auto-generated culprit. It holds whatever products a merchant drops onto the homepage grid, and it is accessible as a standalone URL. Many themes link to it from the logo or from the footer. It almost always duplicates either the homepage itself or a curated "featured" collection, and Google has to work out which one deserves the ranking. Usually nobody wins.
The Canonical Tag Trap in Shopify's Default Behaviour
Here is the part that nobody explains properly. Shopify's default canonical logic is not uniformly bad. On /collections/x/products/y it does the right thing and points to /products/y. Good. On paginated collection URLs it self-references to the paginated path, which since 2021 has been the recommended approach, letting each page get indexed on its own terms. Also fine.
The break happens on two specific URL patterns, and they are the patterns that generate the most duplicate content on a typical store.
The first is tag-filtered collection URLs. When a theme exposes tag-based filters, Shopify turns each filter selection into a crawlable URL like /collections/shirts/red or /collections/shirts/red+cotton. These URLs get a self-referencing canonical. They are fully indexable. They contain roughly the same product set as the parent collection, just pre-filtered. Google sees a dozen near-identical pages competing with the one you actually want to rank, and ranks none of them well. This is the single biggest native SEO issue on the platform and Shopify does nothing about it.
The second is /collections/all. The canonical self-references. Nothing tells Google this is a junk URL. For stores where /collections/all genuinely duplicates a primary curated collection, which is most stores, you are telling Google both URLs deserve to rank. They will split the signals and neither will.
The faceted filters under the Storefront Filtering API are slightly better behaved, generating query parameters like ?filter.v.option.color=red rather than path segments, but they still self-reference and still dilute authority unless you intervene. We noindex every one of them unless the filtered result has verifiable search demand, in which case it gets promoted to a proper landing page rather than a filtered collection URL.
The Canonical and Rewrite Pattern We Ship
The fix is not complicated but it does require editing theme.liquid, collection.liquid, and robots.txt.liquid together. The three pieces have to agree or you will end up with contradictory signals. Here is the pattern we deploy on every store we take over.
In theme.liquid, the canonical block gets rewritten to handle the edge cases explicitly. On tag-filtered collection URLs the canonical points back to the parent collection, stripping the tag from the path. On /collections/all it points to the primary curated collection the merchant designates as their "shop all" destination, usually their best-selling or featured collection. On every other URL we fall through to canonical_url, which handles the product duplication correctly on its own.
In collection.liquid, we add a robots meta tag at the top of the template. If current_tags is populated, meaning the page is a tag-filtered view, we emit noindex,follow. Google drops the page from the index but still crawls the product links inside, which preserves the internal linking value. If current_tags is empty, we emit nothing and let the default behaviour stand.
In robots.txt.liquid, we disallow /collections// to cover the path-based tag filter pattern, and we disallow any URL containing ?filter. to cover the faceted filter parameters. We keep /collections/ itself open because the parent collection URLs must remain crawlable. We also disallow /collections/all outright once we have redirected it, because some merchants want it gone entirely rather than canonicalised.
The last piece is a 301 redirect on /collections/all to the primary shop collection, which we configure in Shopify's URL redirects admin. This is cleaner than relying on the canonical alone because it removes the URL from Google's index entirely within a few weeks and stops the crawl budget drain at source. For stores where /collections/all has accumulated backlinks over the years, we check the backlink profile first and only redirect if we are confident the link equity will flow correctly to the new target.
Taken together, this pattern eliminates around ninety percent of the duplicate content issues we find on the platform. The remaining ten percent live in the homepage, /collections/frontpage, and vendor-auto-generated collections, which we address case by case depending on what the theme is doing with them.
Why Collection Pages Lose to Custom Landing Pages for Head Terms
Here is the insight that shifts how we build Shopify SEO for serious merchants. A Shopify collection is not a marketing asset. It is a database query with a template wrapped around it. You get a product grid, a title, a description field, and whatever filter UI your theme ships. You cannot mix content formats. You cannot feature three products above a buying guide and eight more below it. You cannot hand-curate sections, add video, interleave FAQ blocks, or link out to related guides in the middle of the page. The template dictates the structure and the template is built for browsing, not for ranking.
For long-tail product queries this does not matter. Someone searching "navy merino crew neck size M" wants to see products, fast, and a filtered collection is perfect. For head-term category keywords, the picture is completely different. Search "running shoes" or "organic cotton t-shirts" or "nursery furniture" and the results are dominated by pages that look almost nothing like a Shopify collection. They lead with editorial content, include buying guides, compare sub-categories, embed expert quotes, answer common questions, and only then show product grids. The ranking pages are treating the keyword as an informational query with commercial intent behind it. A bare collection grid cannot compete.
This is why we have moved most of our clients' head-term targeting off collections entirely and onto metaobject-driven landing pages.
The Metaobject Landing Page Pattern
Shopify launched metaobjects in late 2022 and the feature matured through 2024 into something genuinely useful for content-led SEO. A metaobject is a custom content type you define yourself, with whatever fields you want. We define a "Category Landing Page" metaobject with fields for hero image, intro copy, a buying guide body, a list of featured products as references, a list of sub-collections as references, FAQ entries as a repeatable group, related guides as references, and a SEO title and meta description pair.
The metaobject renders through a dedicated template. We build one called metaobject.category-landing-page.liquid that lays out the fields as a full editorial page. Hero section with heading and intro, a featured products band pulling the referenced products directly, a buying guide section rendered from rich text with proper H2 and H3 structure, a sub-category band linking down to the actual Shopify collections, an FAQ block that also emits FAQPage schema, and a related guides footer. The merchant fills in the metaobject entry in admin and the page builds itself.
The URL matters. By default a metaobject renders at a path like /pages/category-landing-page-entry-handle which is neither memorable nor keyword-friendly. We use Shopify's URL redirect admin to create a clean alias, so /running-shoes or /category/running-shoes maps to the underlying metaobject URL. From a crawl and indexing perspective this looks like a normal page, it emits proper canonical tags, and it sits above the Shopify collection for "running shoes" in our internal linking hierarchy.
The advantages over a plain collection are substantial. Content is fully editorial rather than templated. Featured products can be hand-picked across multiple collections rather than derived from a tag rule, so you can showcase your best sellers regardless of category structure. The page does not re-render itself when a product gets tagged or untagged, which means no accidental content churn. Schema markup is under your control and can include ItemList, FAQPage, and BreadcrumbList cleanly. And because the page is detached from the collection system, you can experiment with layout, add video, split-test intro copy, and treat it like a proper marketing page.
The collection still exists. It sits at /collections/running-shoes and handles the filtered browsing use case for people who land there from internal links or from long-tail queries. The metaobject landing page at /running-shoes handles the head term and funnels visitors either down into the collection or directly into the featured products. Internal linking flows both ways. Neither page tries to be the other.
The Faceted Filter Noindex Rule
A short section that is easy to skip but expensive to get wrong. Every faceted filter URL on a Shopify store should be noindex,follow by default, with a small allowlist of filtered combinations that have verifiable search demand and deserve their own indexed page.
The default behaviour, where Shopify emits self-referencing canonicals on filtered URLs and lets Google index them, is an SEO disaster on any store with more than a handful of product attributes. A store with five colour options and four size options produces twenty filtered combinations per collection, each one a near-duplicate of the parent. Across a hundred collections that is two thousand near-duplicate URLs competing with your real pages.
The rule we apply is simple. Noindex every filtered URL at the template level using the current_tags and request.parameters checks. Then for each filtered combination that has real search volume, such as "red running shoes" or "mens organic cotton t-shirts", build a proper metaobject landing page as described above, with editorial content and a URL that matches the keyword. Link to it from the parent collection using filter-style UI, so users still get the filtered experience, but the indexed page is the landing page, not the filtered collection view.
This flips the model. Instead of letting Shopify generate thousands of thin filtered pages and hoping Google sorts them out, you build a curated handful of landing pages that actually target the queries worth ranking for. The filtered URLs exist as a shopper convenience but stay out of the index.
What to Audit on Your Store This Week
Pull up your theme.liquid and check the canonical block. If it uses anything other than canonical_url for the general case, or if it does not handle tag filters and /collections/all explicitly, you have the default-Shopify duplicate content problem. Run a crawl of your store with any SEO tool and look for /collections/all in the results. Look at how many pages it has, how often it is linked to internally, and whether it is in your sitemap. Check Search Console for impressions on /collections/all and its paginated children, because that is exactly the traffic that should be flowing to your curated collections instead.
Look at your faceted filter URLs. Pick a collection, apply a filter, grab the URL, view source, and check the canonical and robots tags. If the canonical self-references and there is no noindex, you are leaking.
Finally, list your top ten category keywords by search volume. For each one, look at what is currently ranking on Google. If the ranking pages lead with editorial content and buying guides, your bare Shopify collection is never going to catch them. Those are the keywords where a metaobject landing page is going to pay for itself inside a quarter.
Where WitsCode Comes In
We do this work on around a dozen Shopify stores at any given time. The URL audit and canonical rewrite is usually a two-day engagement. The metaobject landing page build is a longer project, typically scoped per landing page depending on how much editorial content the merchant wants to commission. We ship the metaobject definition, the Liquid template, the URL redirects, and the schema markup, and we hand over a page the merchant can populate and extend without touching code.
If your Shopify collection pages are stuck on page three for the keywords you want to win, the URL tree is almost certainly part of the reason. -> Start with a fifteen-minute review of your theme.liquid and Search Console duplicate URL report, then decide whether a full rebuild is worth the investment. Most of the time it is, because the work compounds across every category you target.
Get weekly field notes.
Practical writing on shipping products, straight to your inbox. No spam.
Need help with this?
Shopify Development
We design and build web apps, MVPs, and SaaS products. Talk to us about what you are working on.
Talk to usWant to discuss ecom for your business?
Start a project and we'll talk through where you are, what's working, and the highest-leverage moves for the next 90 days.

