← Insights

Shopify collection filter URLs: what Google crawls and what to block

How Shopify filters become crawlable URLs, what the default robots.txt and canonical already cover, and the three places filtered pages still leak crawl effort.

8 min read

Contents · 6 sections

Why do filters turn one collection into thousands of URLs?

Shopify's storefront filtering documentation states the mechanism in one sentence: when filters are applied, they are reflected in the collection or search URL through URL parameters. The structure is filter.filter_scope.attribute=value, so a product-type filter reads filter.p.product_type=shoes and a variant colour reads filter.v.option.color=red. Combined on the all collection, the documented example is:

/collections/all?filter.p.product_type=shoes&filter.v.option.color=red

The filters can be built on availability, category, price, product tags, product type, vendor, variant options and metafields. Different filters combine with AND logic and the values within one filter with OR. That is where the count explodes. A collection with four filters of six values each does not have 24 filtered pages; every selection of values across the filters is its own address, and the order the parameters appear in can create yet another. Shopify even documents two spellings for the same multi-value selection, filter.v.option.color=red,blue and filter.v.option.color=red&filter.v.option.color=blue, which are two URLs for one page of products.

Google describes the same shape in its guide to managing crawling of faceted navigation URLs. Faceted navigation based on URL parameters, it says, can generate infinite URL spaces, and because the URLs look new, crawlers typically access a very large number of them before concluding they are useless. The two harms it names are overcrawling and slower discovery of the new pages you do want found.

What does Shopify do about it by default?

Two things, both of which you can read for yourself.

The first is robots.txt. Open /robots.txt on your store and look for the collection rules. On Shopify's Horizon demo theme, which we fetched while writing this, the default file contains these lines:

Disallow: /collections/*sort_by*
Disallow: /collections/*filter*&*filter*

The first blocks sorted collection URLs. The second blocks any collection URL carrying two or more filter parameters, which is the combinatorial part. A single filter, such as one colour, is not blocked. That is a defensible default: one filter can be a useful landing page, two or more rarely are. The same rules appear in a second copy prefixed /*/ for market subfolders.

The second is the canonical tag. Shopify exposes the page's canonical through the canonical_url object, which themes print in the head. Our canonical URL guide covers what it emits for sorted, filtered and paged collections, and the table in it is the thing to compare your own pages against. The short version is that the canonical for a filtered collection points back to the collection root.

Between them, the two defaults cover the sensible middle. They do not cover three situations that account for most of the trouble we see.

Where does the default protection stop?

Links the crawler can follow. A canonical and a robots.txt rule govern what Google does after it finds a URL. They do not stop the URL from being found. If every filter value in the sidebar is rendered as a plain a href to its filtered URL, every collection page links to dozens of filtered variants and the crawler follows them. Google's guide says that rel="canonical" may over time decrease the crawl volume of non-canonical versions but is generally less effective than robots rules, and that rel="nofollow" helps only if every anchor pointing at a URL carries it. Most filter UIs on Shopify themes are built with JavaScript that updates the URL on click, which is fine, but an app-built filter sidebar may output real links. Check which you have.

Single-filter URLs you did not choose. Because one filter is not blocked, a store with a dozen options per collection can have a dozen crawlable single-filter pages per collection. Some of those deserve to exist. A "black leather bags" landing page with its own heading and description can rank. A filter for "in stock" is a state of the inventory, not a page. The default does not know the difference; you do.

Apps and parameters outside Shopify's own set. A filter or search app can add its own query parameters, and those are not in the default robots.txt. They are also not in the canonical logic unless the app handles them. The URL pattern in the address bar after you use the filter tells you whether the app uses Shopify's filter. parameters or its own.

How do you see which filtered URLs Google crawls?

Three checks, in order, each a few minutes.

First, run the filter yourself. Open a collection on a phone-sized window, apply one filter, then two, and read the address bar after each. Note whether the parameters are Shopify's filter. set. View the page source and search for canonical; confirm it points to the bare collection.

Second, read /robots.txt and compare it with the lines above. If your file has been edited through a robots.txt.liquid template, check that the collection rules were not removed. Shopify's robots.txt customisation documentation describes the template and the Disallow lines it generates by default.

Third, in Search Console, open the Page indexing report and look at the reasons. A large count under "Alternate page with proper canonical tag" for URLs containing filter. means the canonical is working and Google is spending crawl effort finding that out. A count under "Blocked by robots.txt" for sort_by and multi-filter URLs is the default doing its job. A count of filtered URLs under "Crawled - currently not indexed" or indexed outright is the finding. The Crawl stats report under Settings shows how much of Googlebot's requests land on filtered paths; if that share is large on a small catalogue, the filters are costing discovery of new products.

What should the filtered URLs look like if you want them indexed?

Most stores should not index filtered pages. A few should, for categories where shoppers search with a filter in the query. Google's guide gives the conditions for URLs that stay crawlable, and they translate directly:

  • Use the industry-standard & to separate parameters. Commas, semicolons and brackets are hard for crawlers to recognise as separators. Shopify's multi-value form with a comma is the case to watch: if a filtered page is meant to be indexed, prefer the repeated-parameter form in the links you generate.
  • If filters are encoded in the path, keep the order of filters logical and fixed, and allow no duplicates. The same selection must have one address.
  • Return a 404 status for a filter combination that has no results, rather than a 200 with an empty grid or a redirect to a common error page. This is the point on Shopify that needs checking: apply a combination you know returns nothing and read the status in DevTools' Network panel. If you get a 200, an empty page is crawlable and can be indexed as a thin duplicate.

For a page you do want indexed, the better route on Shopify is not a filter at all. Make it a collection: a real collection with a handle, a heading, a description, a place in the navigation and a self-referencing canonical, populated by a smart collection rule. Filters then stay what they are for, which is helping shoppers narrow a list.

What should you fix first, and how long does it take?

  1. Look at the sidebar markup and the address bar after a filter click (ten minutes). If the links are real anchors to filtered URLs, change them to the theme's JavaScript-driven pattern or ask the app vendor how to stop them being crawlable.
  2. Compare robots.txt with the default rules and restore anything removed (ten minutes). If you use a customised template, keep the filter and sort_by rules.
  3. Read the Page indexing report for filter. URLs that are indexed, and decide for each whether it is a landing page (turn it into a collection) or noise (block or leave to canonical) (an hour).
  4. Test the empty combination for its status code (five minutes).

Stores with a small catalogue and a handful of filters usually need step one and step two only. If you would rather have your filtered URLs, their canonicals and the crawl share they take measured on your own store, that is part of what our Store Teardown looks at. Related reading: the collection page schema guide covers what Google reads on the category page itself, and the sitemap guide covers which collection URLs Shopify lists in the first place.

Next step

Own your growth.Start with the teardown.

Read it, then decide whether you want us to fix what it finds.