Skip to content
Ecom

Collection Page Filtering: UX Decisions That Hurt or Help Conversion

Filter-apply behaviour, facet counts, mobile drawers, and URL persistence. The Shopify collection filtering defaults that kill conversion and the patterns we use instead.

By WitsCode9 min read

Filtering is the part of a Shopify store where the most conversion leaks quietly. The product detail page gets all the optimisation attention because it is where the add-to-cart button lives, but a shopper who never reaches the right product never sees that button. Collection pages carry traffic from paid ads, organic search, and on-site browsing, and the filter interface on those pages decides whether a visitor narrows down to something they want or gives up and leaves. Across the 250-plus Shopify stores we have touched at WitsCode, weak filtering is the second-largest source of lost collection-page revenue behind slow loading. This article covers the filter-apply question, facet count ceilings, mobile drawer mechanics, URL persistence, indexing, and the ordering rules we ship on every project.

Instant-Apply Versus Apply-Button Is a Device Question

Most theme documentation treats this as a binary choice and picks one pattern for both desktop and mobile. That is the mistake. The correct answer is different for each device, and shipping the same pattern everywhere costs conversion on one of them.

On desktop, instant-apply wins. When a visitor clicks a checkbox for a brand or ticks a price band, they expect the product grid to react immediately. Baymard usability testing across multiple rounds has shown that when an apply button exists on desktop, a measurable share of users either click it twice because they forgot it existed after making a selection, or walk away assuming the page is broken when the grid does not update. The cognitive model on a large viewport with a persistent left sidebar is "I am shaping the grid as I go." Any delay breaks that model. Desktop users also rarely misclick because cursor precision is high, so accidental filter toggling is not a real risk.

On mobile, the picture inverts completely. A mobile drawer sits over the grid, each tap triggers a re-render, and every re-render delays the response to the next tap because the drawer has to repaint and re-bind events. Instant-apply on a mobile drawer feels laggy even on fast connections because the user is queuing taps faster than the network can acknowledge them. Worse, the touch surface is large and imprecise, so accidental filter firing is common. The right mobile pattern is a deferred apply button, pinned to the bottom of the drawer, showing the live result count so the user can see the cost of their selection before committing. "Apply (42 results)" is one of the highest-value strings in ecommerce UI because it converts a commitment into a preview.

Most Shopify themes, including Dawn and its forks, ship instant-apply on both devices by default. The fix is a small Liquid and JavaScript change to wrap the mobile drawer's filter events in a staging state and only push them to the URL when the apply button is tapped.

The Seven-to-Nine Facet Ceiling

A facet group that shows twenty-four brand names in a scrolling list is not a filter, it is a directory, and directories do not help anyone decide. Human working memory can hold roughly seven plus or minus two items in attention at once. Once a facet list exceeds nine visible values, users stop reading and start scrolling, and scrolling past options is equivalent to not seeing them at all. The brands at position fifteen and below may as well not exist.

The sweet spot for visible facet values per group is seven to nine. Above that ceiling, use one of three patterns. First, truncate with a "Show twelve more" link that reveals the rest on click. This is appropriate for brand and material lists where most traffic converts on the top few anyway. Second, add a search input at the top of the facet group for very long lists such as brand catalogues with hundreds of entries. Third, merge or re-cut the facet entirely, which is usually the right answer. A colour facet with forty-seven Pantone variations should be a colour facet with eight standard buckets that roll up the variations.

Facet value count ("Leather (23)") is not decoration. Baymard lists it as a top-twenty ecommerce UX guideline and our own data across client accounts shows filter engagement drops sharply when counts are removed. The count lets the shopper predict whether their selection will zero out the grid before they click, which avoids the worst filter experience of all: ending up on an empty results page with no path forward. Shopify's native filter renders these counts by default. If your theme strips them for visual cleanliness, put them back.

URL Persistence and the Back-Button Problem

Every filter state on a collection page must live in the URL. Not in a Liquid section's local state, not in session storage, not in a JavaScript variable that resets on reload. The URL. Shopify's native storefront filters do this correctly, producing query strings like ?filter.p.m.custom.material=leather&filter.v.price.gte=50, and any custom filter implementation must follow the same pattern.

Four things break if filter state is not in the URL. The back button stops working the way shoppers expect. A visitor who filters a boots collection to "leather, size 9, under one hundred pounds," clicks into a specific boot, then taps back, expects to return to the filtered grid. If state is in local memory, they return to the unfiltered collection and have to redo every selection. Conversion rate for those sessions collapses because a meaningful share simply leaves. Sharing a filtered link to a friend or pasting it into a marketing email becomes impossible. Page reloads, which happen constantly on mobile when users switch apps, wipe the filter set. And analytics loses the ability to attribute conversions to specific filter combinations, which means you cannot optimise what you cannot measure.

On most Shopify themes the filter layer handles URL persistence correctly. Where it tends to break is custom product-tile links and Ajax-pagination implementations. If your product tiles link to /products/chelsea-black rather than /collections/boots/products/chelsea-black, the back button returns the visitor to the unfiltered collection because the browser history entry does not know the collection context. Always use the collection-scoped product URL inside a filtered collection so the history stack carries the filter params.

Mobile Drawer Mechanics That Convert

The mobile filter drawer is a full-screen or near-full-screen overlay with a specific anatomy. At the top, a header with "Filters" on the left and a "Clear all" text link on the right. Below, the facet groups rendered as collapsible accordions, all collapsed by default except the top two. At the bottom, pinned above the device's navigation bar with enough clearance for iOS home indicators, a sticky apply button showing the live result count.

Collapsed by default matters. A drawer that opens with every facet expanded requires vertical scrolling before the user can see what is available, and the scroll bar hides the apply button. Collapsed accordions let the user scan facet names at a glance, expand only the ones they care about, and keep the apply button a thumb-flick away.

The sticky apply button is where most themes fail. It must remain visible as the drawer contents scroll. It must update its count in near real time as selections change, because that count is the proof that the filter is working. And it must be reachable with a single thumb. Apply buttons stuck to the top of the drawer force the user to scroll back up to commit, which is a friction point large enough to drop completion rates.

One more piece worth calling out: the drawer should not dim the grid underneath because shoppers do not need to see the current grid while filtering. A solid white or dark background is calmer and faster to paint. The dimmed-overlay pattern from modals is appropriate for one-step confirmations, not for multi-step filter selection.

Filter Order and the Decision-Relevant Attribute

The order of filter groups on the page is a product-category decision, not a theme default. Most Shopify themes ship a generic order of Availability, Price, Product type, Brand, and so on. That order is wrong for almost every real store.

The rule we use at WitsCode is: Price first if price is a genuine constraint for the category, then the single most decision-relevant attribute for the vertical, then brand, then secondary attributes. For apparel, that means Price, Size, Brand, Colour. Size before brand because a shopper who wears a specific size cannot wear a brand that does not stock it, so filtering on size first prevents wasted clicks into unavailable options. For power tools, Price, Voltage, Brand, Weight. For bags, Price, Capacity, Brand, Colour. For beauty, the vertical inverts and price usually drops below skin type or shade because buyers start with a match problem before a budget problem.

Colour is the facet most often placed too high. Colour decisions usually happen on the product detail page, where a hero image and swatch picker make the decision concrete. On the collection page, colour should be available as a filter but not the first thing the shopper sees. The exception is pure fashion with heavy colour-driven browsing, where colour can move up.

Hiding facets that match zero products is a small detail that matters. A facet group that lists sizes the current collection does not stock is a source of dead clicks and empty result screens. Disable or hide any facet value with a count of zero, and reserve the top of the group for the highest-count values.

The Indexing Trap

Filter combinations generate URLs, and left alone Google will crawl and index every one of them. A collection with six facets and five values each generates more than fifteen thousand URL combinations, most of which are thin duplicates of the unfiltered page. This dilutes crawl budget, confuses the canonical signal, and can trigger thin-content or duplicate-content downgrades.

The correct configuration has three parts. Set <link rel="canonical"> on every filtered collection view to point at the unfiltered collection URL. Shopify's native setup handles this on the faceted filter pages it ships, but custom filter apps often miss it. Add <meta name="robots" content="noindex,follow"> to filter combinations that do not represent strategic landing pages. The "follow" is important because you want Google to still traverse the links out from the page even if it is not indexing the page itself. And leave single-facet URLs that match real search demand indexable. "Leather boots" gets meaningful search volume, so /collections/boots?filter.p.m.custom.material=leather can and should be crawlable with a unique title tag, a custom meta description, and a short intro paragraph if you want it to rank for that query.

Do not use robots.txt disallow for filter URLs. That blocks Google from crawling the page to see the canonical or noindex tags, which means the URLs can still end up in the index as partial entries with no snippet. The meta robots tag is the right tool because it lets the crawler in, see the directive, and behave correctly.

What We Ship at WitsCode

On every Shopify collection page we touch, the filter layer gets audited against six criteria before we consider the build complete. Desktop uses instant-apply, mobile uses deferred apply with a live count on the button. No facet group shows more than nine values at once without a truncation or search pattern. Every facet value displays its result count. Every filter state writes to the URL and survives the back button. Filter order is tuned to the vertical, with the decision-relevant attribute near the top. And the indexing configuration treats filtered URLs as noindex-follow by default, with explicit indexable exceptions for the handful of filter combinations that match real search demand.

Filter engagement under fifteen percent of collection sessions is the symptom we see most often on stores that have not had this work done. Pushing engagement into the twenty-five to thirty-five percent range is where the conversion rate moves, and the lift is rarely from adding filters. It is almost always from removing the wrong ones, reordering the rest, fixing the mobile drawer, and getting the URL layer right. The pattern is boring, repeatable, and it works on every store we ship.

The filter is not a feature the shopper admires. It is a tool they use unconsciously to get to a product they want. The stores that treat it that way, and invest in the small mechanics rather than chasing novel interactions, convert better. That is the whole job.

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 us

Want 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.