Skip to content

field note

Faceted navigation SEO: stop filter URLs flooding Google (WooCommerce and Shopify)

Ecommerce

Shahid AliSeptember 3, 2026all posts

Faceted navigation SEO: stop filter URLs flooding Google (WooCommerce and Shopify)

Faceted navigation SEO comes down to one decision most stores never make on purpose: which of the filter URLs, the ?filter_color=, ?orderby=, ?min_price= and ?sort_by= variants, should Google crawl at all. Left alone, a WooCommerce or Shopify catalogue with a few hundred products can generate hundreds of thousands of crawlable URLs, and Google’s own crawling documentation now says, in plain words, to block most of them.

Do filter URLs hurt SEO?

Not in the penalty sense. They hurt in the budget sense, and Google names the two harms directly. Faceted URLs “can generate infinite URL spaces”, which causes overcrawling, where Googlebot fetches “a very large number of faceted navigation URLs before the crawlers’ processes determine the URLs are in fact useless”, and slower discovery crawls, because “if crawling is spent on useless URLs, the crawlers have less time to spend on new, useful URLs”.

On a small store that costs you nothing visible. On a catalogue that adds products weekly, it is the difference between a new product being crawled in a day and sitting in “Discovered, currently not indexed” for a month. The crawl budget documentation lists “differently sorted versions of the same page” as its first example of URLs worth blocking, and gives “a large portion of total URLs classified as Discovered - currently not indexed” as the signal that budget is the problem.

Should I block filter URLs in robots.txt or noindex them?

Block them, if you do not want them in Google. That is Google’s first recommendation and the one it puts the most weight behind: “Use robots.txt to disallow crawling of faceted navigation URLs. Oftentimes there’s no good reason to allow crawling of filtered items, as it consumes server resources for no or negligible benefit.”

Filter URLs: Google's two answers, and what each method actually does Do you want the filtered pages in Google at all? No: stop the crawl robots.txt: Disallow: /*?*orderby= Disallow: /*?*filter_ or filters in URL fragments (#color=red), never crawled canonical and nofollow: "generally less effective" noindex: still fetched, then dropped, budget spent Yes: make them crawlable cleanly standard key=value&key=value parameters, no commas or brackets canonical each combination to the version you want indexed return 404 for empty results, not a "no products" page index only facets with real search demand From the faceted navigation and crawl budget documentation, Google Search Central. A canonical consolidates indexing; it does not stop crawling.

The documentation gives a literal example, which I have adapted to WooCommerce’s parameter names:

User-agent: Googlebot
Disallow: /*?*orderby=
Disallow: /*?*filter_
Disallow: /*?*min_price=
Disallow: /*?*max_price=
Allow: /*?products=all$

The second option is fragments. Put the filter state after a # instead of a ?, and because “Google Search generally doesn’t support URL fragments in crawling and indexing”, the filter “will have no impact on crawling (positive or negative)”. It is the cleaner fix and the harder one to retrofit, since it means the filtering happens in the browser.

Then the sentence people skip: canonical and nofollow are “generally less effective in the long term than the previously mentioned methods”. A canonical tag on a filter URL is a consolidation hint, not a crawl instruction. Google still fetches the URL to read the tag, and keeps fetching it. Noindex is worse for budget, because as the crawl budget page says, Google “will still request, but then drop the page when it sees a noindex meta tag or header, wasting” the crawl. Noindex has a place, which is when a filter page is already indexed and you want it out of the index before you block it. I compared the two directives generally in noindex vs robots.txt; for filter URLs the order is noindex first, wait for the drop, then disallow.

Why are my WooCommerce filter URLs in Google?

Because WooCommerce ships its parameters live and crawlable by default, and most themes link to them from every category page. The set to know: orderby for sorting, min_price and max_price from the price slider, filter_colour, filter_size and every other filter_<attribute> from the layered navigation widget, rating_filter from the rating widget, paged for pagination, and add-to-cart on every product button. The search parameter s is a separate infinite space of its own.

The SEO plugin usually stops these from being indexed, by writing a canonical to the clean category URL, but read the previous section again: that stops indexing, not crawling. View the source of a filtered category on your store and check what the canonical says. If it points to the filtered URL itself, the plugin is self-canonicalising and every filter combination is an indexing candidate, which is how a store ends up with more filter pages than products in the index.

What I have not found on a WooCommerce store out of the box is a robots.txt rule for any of these. The plugin-generated file blocks the admin area and nothing else. The one parameter WordPress does handle for you is its own search, ?s=, which core noindexes without a robots.txt rule and without any help from you; that is the model to copy here, not a disallow. Every store I have audited that had filter parameters blocked had them blocked because someone added the rules. I flagged one such set on a store in blocked by robots.txt, where dozens of ?filter= and ?orderby= URLs sat in that status and every one of them was the rule working as intended.

Shopify is the opposite case. Its default robots.txt already disallows /collections/*sort_by* and the + and %2B tag-combination URLs, I checked three live stores today and all three carry the same block, and you can extend it through the robots.txt.liquid template. If you are on Shopify and sort URLs are being crawled anyway, someone has edited that template. That block handles sort and filter parameters; it does not touch the separate /collections/.../products/ duplication every Shopify product carries by default, which Shopify duplicate content covers on its own.

Which filter pages should be indexed?

The ones people search for. A category filtered to a brand or a colour that has its own search demand, “red running shoes” rather than “running shoes sorted by price ascending”, can be worth indexing as a landing page. Google’s second set of recommendations is for exactly that case, and it is short: use standard key=value parameters joined with &, not commas or brackets; keep the canonical consistent, so ?color=red&size=9 and ?size=9&color=red resolve to one URL; and return a real 404 when a filter combination has no products, instead of a page that says “no products found” with a 200 status. That last one is a soft 404 factory, and a store with a price slider generates them by the thousand.

The honest version of “index some facets” is a short allow-list. A handful of filter URLs that earn a landing page, linked from the category with clean URLs, and everything else blocked. Nobody needs the sort order indexed.

How do I find how much crawl budget filters waste?

Without server logs, Search Console gives you enough. Open Settings, then Crawl stats, and read two breakdowns. By response tells you how many fetches ended in 404, which on a store with empty filter results is often the largest block after 200. By purpose splits refresh crawls from discovery crawls; a store where discovery is a sliver and refresh dominates is spending its crawl re-reading the same pages. Click into either row and scan the sample URLs for ?filter_, ?orderby= and ?min_price=. Crawl stats shows samples, not totals, so I do not turn it into a percentage. I count how many of the samples are parameter URLs, and on a store with an unmanaged filter set it is most of them. If the report is blank, Crawl stats missing data explains why.

The Page indexing report shows the same waste from the other end, and every status maps to one cause. Filter URLs with a canonical Google agreed with land in “Alternate page with proper canonical tag”. Filter URLs with no canonical at all land in “Duplicate without user-selected canonical”. The bulk of a badly managed set lands in “Crawled, currently not indexed”, and when the budget runs out before the new products, the products land in “Discovered, currently not indexed”. That last pairing is the whole argument. The filters got crawled and the products did not.

What replaced the URL Parameters tool?

Nothing, and Google’s stated reason is that nothing was needed. When the tool was retired in 2022, the announcement said “only about 1% of the parameter configurations currently specified in the URL Parameters tool are useful for crawling”, and that “Google’s crawlers will learn how to deal with URL parameters automatically. If you need more control, you can use robots.txt rules.” Any guide still telling you to set parameters to “No URLs” in Search Console is describing a screen that no longer exists.

What I do on a store

The baby products store I have worked on longest is a WooCommerce catalogue, and the shape of the job says everything about faceted navigation. Over 118 days I submitted 1,006 URLs to Google, but the tracking list that mattered held 409 priority URLs, the products and categories that were meant to rank. The gap between those two numbers is what a catalogue generates once filters, pagination and variants are counted. The baby products store case study has the numbers, and anatomy of a 118-day indexing job has the timeline.

The order I work in, when the filters are already indexed:

  1. Fix the canonicals first, so every filter combination points where you want it, and self-canonicalising filter pages stop being indexing candidates.
  2. Add noindex to the filter URLs you want out, and wait for the Page indexing report to show them dropping.
  3. Only then add the robots.txt disallow rules. Adding them first freezes the pages in the index with the old status, because Google can no longer fetch them to read the noindex.
  4. Keep the allow-list of filters that deserve a landing page, and link to those with clean URLs from the category.
  5. Recheck Crawl stats a month later. The share of parameter URLs in the samples is the number that should have moved.

One distinction before you apply any of this more widely. Paginated URLs look identical to faceted ones in the Page indexing report and need the opposite treatment: facets multiply URLs without adding content, so noindexing them is right, while pagination is how Google reaches your older content, so noindexing it costs you internal links. If you are about to apply a filter rule to /page/2/ as well, read what Google actually does with paginated archives first.

For the wider picture of where those fetches go, the fetch cost of every Search Console status sets filters and sorts against the other things eating your crawl.

Sources

  • Google Search Central, managing crawling of faceted navigation URLs, for the two harms, the robots.txt and fragment recommendations, the “less effective” note on canonical and nofollow, and the best practices when facets are indexed, checked 3 September 2026
  • Google Search Central, managing crawl budget for large sites, for sorted versions as a blocking example and the note that noindex still costs a fetch, checked 3 September 2026
  • Google Search Central blog, spring cleaning: the URL Parameters tool, March 2022, for the 1 per cent figure and the robots.txt recommendation, checked 3 September 2026
  • Google Search Central, URL structure best practices, for fragment handling, checked 3 September 2026
  • First-hand: three live Shopify stores’ robots.txt files, fetched 3 September 2026, for the default sort and tag-combination disallow rules; and the baby products store case study, 1,006 URLs submitted over 118 days against 409 priority URLs