Skip to content
ThemesIonic — home
WooCommerce

WooCommerce Filter Not Working

Filters fail in three distinct ways: nothing happens, everything disappears, or the results are wrong. Each points at a different layer — the query, the attribute data, or a cache serving a filtered page to everybody.

5 min read intermediate

Name the symptom before touching settings. Three different faults get reported as "the filter is broken", and they have nothing in common:

Symptom Layer at fault
Clicking a filter does nothing, URL unchanged JavaScript, or a filter that cannot act on this query
URL changes, no products returned Attribute data, lookup table, or over-strict conditions
Wrong products, or the same results for everyone Caching

Work out which one you have, then read only that section.

Filters act on the main product query

Layered navigation modifies the query WordPress is already running for the page. That single fact explains most "nothing happens" reports.

It works on: the shop page, product category and tag archives, and attribute archives.

It does not work on: a page containing a products shortcode, a page builder's product grid, a block-based grid outside the shop template, or any other secondary query. Those run their own query that the filter widgets never see — the distinction is set out in displaying WooCommerce products with shortcodes.

If filtering is needed on a custom page, either make that page a real product archive or use a filter plugin that explicitly targets the grid you are using. Mixing a core filter widget with a builder grid cannot be configured into working.

Attributes have to be global and archive-enabled

Two kinds of attribute look identical on the product edit screen and behave completely differently.

Global attributes are created under Products → Attributes, exist as taxonomies, and can be filtered.

Custom product attributes are typed straight into a single product's Attributes tab. They are stored as post meta on that product only. Nothing can filter on them, and no plugin can fix that without converting them.

Even a global attribute needs Enable archives ticked to appear in layered navigation. Check that first — it is the single most common cause of a missing filter.

Converting local attributes to global ones after the fact means recreating the attribute, adding its terms, and reassigning them across the catalogue. Bulk edit or a CSV round trip through the product importer is the practical route.

Rebuild the lookup table

WooCommerce keeps a product attribute lookup table so filtering does not have to run expensive meta queries. After a bulk import, a bulk edit, a migration or a failed update, it goes stale — and a stale table returns nothing for attributes that plainly exist on products.

Regenerate it from WooCommerce → Status → Tools:

  • Regenerate the product attributes lookup table — the fix for empty filter results.
  • Recount terms — fixes product counts shown beside each filter option.
  • Clear transients — clears cached widget output and term counts.

On a large catalogue this runs in the background through the scheduled action queue, so confirm the queue is actually processing; a stalled queue leaves the job pending forever. WooCommerce database update not working covers a queue that will not drain.

Empty results with a correct-looking URL

If the URL gains ?filter_colour=blue and the archive says no products were found, work through the exclusions in order:

  1. Catalogue visibility. Products set to "hidden" or "search results only" never appear in a filtered archive.
  2. Stock status. With "hide out of stock items" enabled, an option can legitimately match nothing.
  3. Term assignment. Open a product you expect to match and confirm the attribute term is ticked and marked Visible on the product page — a term used only for variations still needs to be assigned.
  4. AND versus OR. Query type "and" requires products to carry every selected term at once, which returns nothing surprisingly often across two attributes.
  5. The lookup table, from the previous section.
  6. A category context. Filtering inside a category intersects with that category, so a matching product elsewhere in the catalogue will not appear.

Caching filtered pages

Filtered URLs carry query strings. Two caching misconfigurations produce misleading results:

  • The cache ignores query strings, so every filter combination is served the same stored page. The filter looks broken because the results never change.
  • The cache stores every combination, which is not wrong but fills the cache with thousands of near-duplicate pages and slowly starves it.

Set the caching layer to vary on the filter_* and query_type_* parameters, or exclude filtered URLs from the page cache and let object caching carry the load. The layer model is in choosing a WordPress cache plugin. After any change, purge everything and retest in a private window — how to clear the WordPress cache.

An object cache holding stale term counts causes a milder version: correct products, wrong numbers in brackets. Recount terms and clear the object cache together.

AJAX filtering that stalls

Filter plugins that update results without a page reload add a failure point. When a click spins forever or does nothing:

  • Open the browser console. A JavaScript error names the file; a failed request to admin-ajax.php or a REST route names the layer.
  • A 403 on that request usually means a security plugin or firewall blocking it, or an expired nonce on a page served from cache.
  • Script combination or deferral in an optimisation plugin regularly breaks filter scripts. Turn those options off and retest before anything else — the pattern is the same one described in how to fix plugin conflicts.
  • A stale theme template override in the theme's woocommerce/ folder can strip the wrapper the filter script expects to replace.

Confirm it is not the theme

Reproduce with a default theme and only WooCommerce active, on a staging copy. If filtering works there, reintroduce the theme first — themes override product archive templates far more often than plugins do — and then the plugins in batches.

Themes that ship their own filter or "shop builder" frequently conflict with the core widgets. Use one or the other, never both.

Verify

Check a single-attribute filter, two attributes together, a filter combined with a price range, a filter inside a category, and a combination you know matches nothing — that last one should say so cleanly rather than showing the unfiltered catalogue. Do it logged out, with caches purged, and confirm the product counts beside each option match the results you actually get. If you are still weighing native layered navigation against a plugin, the trade-offs are in WooCommerce product filter.

Frequently asked

Layered navigation only offers global attributes created under Products → Attributes with Enable archives ticked. Attributes typed directly into a single product are custom and local to that product, so nothing can filter on them.
Usually the product attribute lookup table is out of date after an import or a bulk edit. Regenerate it from WooCommerce → Status → Tools. Stock status and visibility filters can also exclude products you expect to see.
Filter widgets act on the main product query. A products grid built with a shortcode or a page builder runs a secondary query, which the filters never touch.

Related guides