Ecommerce SEO
Faceted navigation rules: which filters index, which do not
A decision rule for every filter URL: index it, canonicalize it, or keep crawlers out. The tests a facet must pass, the ladder and platform notes.
By CartKernel · Published
Every filter a shopper can apply is a URL, and every URL needs a decision. There are only three outcomes: the filtered page is indexed as a page in its own right, it is crawlable but consolidated into its parent, or crawlers are kept away from it. The default is the second. The first has to be earned by passing four tests. The third is for the combinatorial space that no store wants crawled, and it is the one most stores never implement.
The three outcomes
| Outcome | Applies to | Mechanism |
|---|---|---|
| Index | A single facet value with demand, inventory and its own content | A static page or collection at a clean URL, self-canonical, in the sitemap, linked from the parent |
| Consolidate | Single facets without demand, and any filter state a shopper reasonably shares | Parameter URL with a canonical to the parent collection, not in the sitemap |
| Keep out | Multi-select combinations, sort, price ranges, view options, everything deeper than one facet | URL fragments for the filter state, or robots.txt rules for the parameter patterns |
The mistake that produces index bloat is treating everything as the second outcome and hoping the canonical holds. Canonicals are a hint, they only work once the URL has been crawled, and the crawling is the cost. Google’s own guidance on faceted URLs is explicit that the choice is between letting the URLs be crawled with consistent parameters and keeping them out with fragments or robots rules.
The four tests for indexing a facet
A facet value gets its own indexable page only when all four hold.
- Demand. People search for the combination. Brand within category almost always qualifies. Material and category often do. Colour and category sometimes do, for a handful of colours. Size and category almost never do.
- Inventory. The page will hold enough products to be worth landing on, and the count is stable. A page that alternates between twelve products and two as stock moves is not a page.
- Distinctness. The page can carry its own title, heading, introduction and buying notes that the parent could not carry. If the only difference is the grid, it is a filter, not a page.
- Singularity. One facet value, no sort applied, no price range, no second facet.
A facet that passes becomes a static collection or landing page at a clean URL, with the content written for it, and is linked from the parent collection with the term as the anchor. This is what our programmatic collection pages work produces at scale, with the four tests as the quality gate.
Facets that never index
Sort order, price ranges, availability, rating thresholds, page size, grid or list view, multi-select of any kind, and any session or tracking parameter. None of these creates a page a searcher wants, and each multiplies the URL count of every collection it touches. Pagination is a separate case with its own rules and is handled with real links and self-referencing canonicals, not as a facet.
The implementation ladder
Work up the ladder until the crawl is under control.
- Canonical on every filtered URL pointing at the unfiltered collection. This is the floor, and on its own it is not enough for a large catalog.
- Consistent parameter handling. One encoding, one parameter order for the same filter state, so that the same combination has one URL rather than several. Google’s guidance asks for this for any facet URLs you do allow to be crawled.
- Fragments or robots rules for the deep space. Put multi-select and sort state after a hash, which crawlers ignore, or disallow the parameter patterns in robots.txt. Robots rules stop crawling but not the indexing of URLs already discovered elsewhere, so use them for what has not yet been crawled and canonicals for what has.
- A 404 for filter states with no products. An empty grid returning 200 is a soft error; Google’s guidance recommends a proper not-found response for combinations that return nothing.
- No crawlable anchors to what you do not want crawled. Filter controls for the kept-out space can be buttons; the promoted pages get real links.
- A sitemap that lists only the indexed outcome. Nothing with a parameter goes in it.
Nofollow on filter links is sometimes suggested as a fix. It is a hint Google may ignore, it does nothing for URLs discovered another way, and it is not a substitute for any rung above.
Platform notes
Shopify. Storefront filtering writes filter state into parameters with a filter. prefix, plus sort_by, on the collection URL. Most current themes set the canonical of a filtered collection to the collection itself, which covers the second outcome. To promote a facet, create a collection at its own handle, usually an automated collection with conditions on tag, vendor or metafield, and give it its own content. The robots file can be edited through the theme’s robots template if parameter patterns need disallowing.
WooCommerce. Layered navigation and filter widgets append their own parameters, and the sort control adds another. The SEO plugin sets canonicals on filtered archives; check that it does. Product attribute archives can be enabled as indexable pages, which is the built-in route to the first outcome when an attribute value passes the tests.
BigCommerce and headless. Faceted search produces parameter URLs whose canonical behaviour depends on the theme or the front end. On a headless build, the rules above are written into the routing layer, which is the one place where all three outcomes can be implemented exactly as intended.
Finding out what is happening now
Three sources, read together:
- Search Console’s pages report. Large counts under “crawled, currently not indexed” and “duplicate without user-selected canonical” that resolve to parameter URLs are the signature of facet URLs being indexed or nearly so.
- A crawl of your own site with parameters left on. Count URLs by pattern.
- Server logs where you have them, to see the share of crawler requests going to parameter URLs. That share is your crawl budget being spent on pages you did not want.
A worked decision, illustrative
Take a footwear store with forty collections and filters for brand, size, colour, width, price and sort. The combinations run to the millions. Applying the tests: brand within collection gives perhaps twenty-five pages with real demand, each promoted to a static collection. Colour within collection gives a few, such as white sneakers and black boots, and the rest stay consolidated. Width gives one, a wide-fit collection built as its own page. Size, price and sort are kept out entirely with fragments, and the remaining single facets carry canonicals to their parents. What was millions of crawlable URLs becomes forty collections, about thirty promoted pages, and a bounded set of single-facet URLs that consolidate cleanly.
What to expect after the change
Crawl requests to parameter URLs fall within weeks in the logs. The indexed count in Search Console falls more slowly, as the already-indexed facet URLs are recrawled and consolidated, and that can run over a few months on a large site. The promoted pages start collecting impressions once they are linked from their parents and included in the sitemap. The parent collections tend to strengthen as their duplicates disappear. None of it is instant, and all of it is visible if you take a baseline first.
Faceted navigation is the single largest source of wasted crawl on stores we audit, which is why faceted navigation SEO is a service line rather than a checklist item. The related questions of whether canonicals alone fix duplicate product pages and whether variants deserve their own URLs follow the same logic: a URL earns indexing by passing the tests, and everything else is consolidated or kept out.