Why WooCommerce search doesn't find your product SKUs
A customer asks you for a part number over the phone, types it into your shop, and reads “No products were found matching your selection.” The product is published, it is in stock, and the number is right there in the SKU field. This is not a setting you missed: WooCommerce search does not read that field.
Three queries on a WooCommerce shop, with no search plugin
Measured on September 28, 2026 on a shop built for it: WordPress 7.1.2, WooCommerce 11.1.2, PHP 8.5.10, the Twenty Twenty-Five theme, 300 published fastener products, no search plugin active. The path measured is the product search form of a classic theme — /?s=…&post_type=product — the one your customers use.
| What the customer types | What the shop returns |
|---|---|
REF-000134the exact SKU of a published product | 0 results. “No products were found matching your selection.” |
M8-30the size written with a dash | 1 product out of the 5 this shop carries in M8×30. And because there is only one, WordPress redirects the customer straight to it. |
rondele inoxone letter missing | 0 results, where rondelle inox returns 15. |
The worst of the three is not a zero
The two zeros are visible. The customer reads “no products”, knows they did not find it, and either calls you or leaves — that is a cost, it is measurable, and at least nobody is misled.
M8-30 is something else. A search that returns a single product shows no list at all: WordPress answers with a redirect (a 302 to the product page), and the customer lands straight on that item. They never saw there was a list. They believe they found it.
On this shop, the one product they reach is a screw in plain steel. The other four M8×30 items — three of them stainless — were displayed nowhere, because they are spelled M8X30, M8x30 or M8 x 30. This is not a missing result, it is a result that lies by omission: the customer leaves with steel where they wanted stainless, and nothing, anywhere, told them the choice existed.
The three failures share one cause
To find a product, WordPress writes LIKE clauses against three columns, and only three: the title, the excerpt and the description (post_title, post_excerpt, post_content). That is the query recorded on this shop, and there is nothing else in it.
No join on the SKU. Neither on the field nor on WooCommerce's product lookup table. A part number that does not also appear in the title or the description is out of reach on this path. If your SKUs are supplier codes — and in fasteners, spare parts and electronic components they are — then your whole part numbering is invisible to your own search. That is the problem our article on searching by part number in B2B describes; here it is measured on WooCommerce.
A LIKE looks for a run of characters, not for a part number. M8-30 becomes LIKE '%M8-30%'. A product titled “Vis M8x30” does not contain that run of characters, so it stays out. On this shop the five M8×30 products are written four different ways — M8X30, M8x30, M8 x 30, M8-30 — because a real catalog is a pile of successive imports. Each spelling typed reaches only the products spelled the same way.
And when the customer types spaces, the noise arrives. M8 x 30 is split into words, and WordPress drops single-letter words: M8 and 30 are left. All five M8×30 products finally come out, together with four that are not, because %30% catches “inox 304”. Nine results, five of them right.
That threshold is not specific to WooCommerce, and that is what makes it interesting. PrestaShop has the same kind of rule, set higher: PS_SEARCH_MINWORDLEN ships at 3, and “M8”, “A2”, “20” are neither searched nor indexed there — measured on PrestaShop 9.1.4. WordPress only drops single-letter words, so “M8” survives. Two platforms, two thresholds, the same decision underneath: an engine written for blog posts, where a short word means nothing. In a technical catalog, the short words are the part number.
The typo has no way out on this path: %rondele% appears in no title. There is no badly tuned typo tolerance to fix, because there is none at all. What we measured is WordPress and WooCommerce on their own: we did not check that no theme and no third-party plugin adds one.
One precision about the path, because it changes the answer. If your shop uses WooCommerce's “Product Search” block, the search goes through the Store API, and that one does read the SKU: on the same shop, REF-000134 returns the right product there. But it looks for the whole string as typed: rondelle inox returns 0, because no title carries those two words in that order. Both paths fail, for two different reasons.
What it costs, and why you never see it
A search with zero results is a visit that stops. The customer does not write in to report that they found nothing: they go elsewhere, or they call you — and a call about a part number your site already carries is a cost, not an extra sale.
And none of it is recorded anywhere: WooCommerce does not keep the searches that returned nothing, and a redirect to the wrong product looks, in your analytics, like a search that worked. Checking takes a minute, and it happens on your shop, not ours: pick any product, copy its SKU, type it into your own search box.
The same three queries, with the Heurix plugin on
Same shop, same 300 products, same theme. The Heurix Search for WooCommerce plugin 0.2.1 is active, the catalog was indexed from the settings screen (300 products, 0 failures), and the engine runs locally. None of the three searches fell back to native search: the plugin's fallback counters are empty.
| Query | Native search | Plugin on |
|---|---|---|
REF-000134 | 0 results | 1 result, the right one. The part number is read as a term. The customer is redirected to its page — and this time the redirect tells the truth. |
M8-30 | 1 product, the one spelled with a dash | All 5 M8×30 items in the top 5 places, whatever their spelling. No redirect any more: there is a list, and the customer sees the stainless next to the steel. |
rondele inox | 0 results | The 15 stainless washers in the top 15 places. Exactly the ones native search returns when “rondelle” is typed without the typo. |
What the plugin does not do better
The count it announces. On M8-30 the plugin returns 45 results: the 5 right ones, then 40 products that share only the diameter or the length with the query — an M18-30, an M8×70, an M8 insert. On rondele inox it returns 195. The right ones come first, which is what matters to a customer looking at page one; but the total shown next to the search box is that one, and the pages after it are noise. The plugin ranks, it does not cut.
And a family of products it finds without showing them. This shop carries 18 stainless washers, not 15: three of them are titled “Rondelle M18 A4”, “Rondelle M20 A2”, “Rondelle M3 A4” — the grade without the word “inox”. Native search never finds them, typo or no typo. The engine does know that A2 and A4 are stainless: it annotates them, and it returns them. At positions 117, 118 and 119 — the eighth page. A customer looking for a stainless washer will not see them either.
These three queries are three queries we chose, on a catalog we generated. They are cases, not a rate.
Installing the plugin
The plugin replaces WooCommerce product search results with the ones the Heurix engine computes. It touches neither your templates, nor your faceted filters, nor your product pages: what changes is which products come out, and in what order.
Installing it. In the WordPress admin, Plugins > Add New Plugin, search for “Heurix Search”: Install Now, then Activate. The public listing is wordpress.org/plugins/heurix-search-for-woocommerce, version 0.2.1. The plugin is free and none of its features is held back for a paid plan: what you pay for is the service, and pricing says so.
What you need. Two things, on the WooCommerce > Heurix Search screen: an API key and the name of your catalog. You test the connection, you run a full indexing, you search. After that, every product you save re-syncs on its own. The WooCommerce page covers the rest.
What it does not do, in 0.2.1. It does not index variations separately: the parent product goes into the index, not each colour or each size. If your catalog discriminates by variation, search will not go down to that level.
And if Heurix does not answer, native WooCommerce search takes back over, one search at a time: your visitors see no outage — they see again the search described in the first half of this article. The settings screen tells you how many searches were served that way, for which cause, and since when.
The measurements
The versions this plugin supports were measured, not declared. On WooCommerce 6.0 and older, the second page of results comes back empty — we know because we ran it, fifteen versions one at a time. The protocol is public: docs/mesures/woocommerce-bornes-2026-09.
One number from this shop is not published, and it is a spectacular one: “ecrou” returns 20 products there, “écrou” returns 0. That is the bench's SQLite drop-in, not WooCommerce — a MySQL database would not behave that way. Everything counted above, on the other hand, depends on neither the database nor the catalog.