Fuse.js Typo-Tolerant Product Search — Free JS Snippet

Fuse.js Typo-Tolerant Product Search with Threshold Tuning · Forms · Plain HTML, CSS & JS · Live preview

CategoryForms

What's included

Features

Typo, abbreviation and dropped-letter tolerance via Fuse.js Bitap matching
Live strictness slider bound to the threshold option
Weighted fields: name, tags, brand and category
Per-result relevance badge derived from includeScore
Matched characters highlighted in the product name
HTML-escaped rendering safe for arbitrary product text
Helpful empty state that points at the fix
Fully client-side and instant for catalogues of a few thousand items

About this UI Snippet

Fuse.js Typo-Tolerant Product Search — HTML, CSS & JavaScript

Screenshot of the Fuse.js Typo-Tolerant Product Search with Threshold Tuning snippet rendered live

Shoppers misspell things constantly, and an exact-match search punishes them for it: "sneekers" returns nothing, so the customer concludes you do not sell sneakers. A fuzzy search closes that gap. Fuse.js scores every item by how closely it approximates the query, so "hedphones", "blutooth speeker" and "mecanical keybord" all find the right products without any dictionary or server round trip.

The single most useful thing this snippet adds is a strictness slider bound to Fuse's threshold option, because that number is the one everyone has to tune and almost nobody understands until they see it. At 0 the search demands exact matches. Around 0.3 it forgives a couple of wrong or missing letters. Push it towards 0.8 and results turn to noise — unrelated products start matching. Dragging the slider rebuilds the index and re-renders instantly, which makes the trade-off visible in seconds instead of by guesswork.

The fields are weighted to reflect how shoppers search: name carries half the score, tags a quarter, then brand and category. A search for "bluetooth" finds products through their tags even when the word is not in the title. One caveat worth knowing: Fuse combines per-key scores multiplicatively, so a perfect hit in a lightly weighted key (a tag) can still outrank a near-perfect hit in a heavily weighted one (the name) — try "wireless" to see it. Weights nudge ranking rather than dictating it, so always test them against real queries. ignoreLocation is enabled so a hit deep inside a long product name counts the same as one at the start. includeScore returns Fuse's error value, where 0 is a perfect match; the card badge converts that into a relevance percentage and colours it green, amber or red so weak matches are visibly weaker.

Highlighting comes from includeMatches, which returns character ranges for the matching field. The renderer sorts the ranges, skips overlaps and escapes every piece of text before it touches innerHTML, so a product name containing angle brackets cannot break the page. When nothing matches, the empty state does not just say "no results" — it points at the strictness control, which is the right remedy. The search runs entirely in memory, so it is instant for catalogues up to a few thousand items; beyond that, move the index to a server or a dedicated search service.

Build with AI

Build, Understand, Optimize, and Extend It With AI

Ask an AI assistant like Claude to add "did you mean" suggestions from the top result, category filter chips that combine with the search, or debounce and highlight the matches in tags too.

Prompt to recreate it

Copy this into your AI assistant of choice to build the effect from scratch, or as a jumping-off point for your own variant:

text
Build a typo-tolerant product search with Fuse.js 7 loaded from a CDN.

Requirements:
- Index a product list with weighted keys (name 0.5, tags 0.25, brand 0.15, category 0.1), ignoreLocation: true, includeScore: true and includeMatches: true.
- Add a strictness range slider that sets the threshold and rebuilds the Fuse instance, showing the current value.
- Render product cards with the matched characters highlighted in the name and a relevance badge (green / amber / red) computed from 1 - score.
- Escape all text before inserting it as HTML.
- Provide quick-try buttons that fill in misspelled queries, and an empty state that tells the user to raise the strictness.

Want to tighten it up first? Run this prompt through the AI Prompt Studio to score it across 8 quality dimensions, catch anti-patterns, and tune the wording for Claude, ChatGPT, or Gemini before you paste it in.

Source Code

Requires
<div class="fp-wrap">
  <div class="fp-bar">
    <input id="fpQ" type="search" placeholder="Search products..." autocomplete="off" aria-label="Search products">
    <div class="fp-tune">
      <label for="fpThr">Strictness <b id="fpThrVal">0.30</b></label>
      <input id="fpThr" type="range" min="0" max="0.8" step="0.05" value="0.3">
    </div>
  </div>
  <div class="fp-try">Try typos:
    <button type="button">hedphones</button>
    <button type="button">sneekers</button>
    <button type="button">blutooth speeker</button>
    <button type="button">mecanical keybord</button>
  </div>
  <p class="fp-count" id="fpCount" aria-live="polite"></p>
  <ul class="fp-grid" id="fpGrid"></ul>
</div>

Step by step

How to Use

  1. 1
    Load a typo exampleThe field starts with "hedphones". Wireless Headphones still appears at the top with a high relevance score.
  2. 2
    Try the other typosClick "sneekers", "blutooth speeker" or "mecanical keybord" and watch the correct product surface.
  3. 3
    Tighten the strictnessDrag the slider to 0. Typo queries now return nothing, and the empty state suggests loosening it.
  4. 4
    Loosen it too farDrag to the right end. Unrelated products creep in with low, red relevance badges.
  5. 5
    Search by tagType "waterproof" or "gps" — products match through their tags even though the word is not in the name.

Real-world uses

Common Use Cases

SHOP
Store and catalogue search
Give shoppers forgiving search without a search backend. Combine with the price range filter for a full filter bar.
Help centre article search
Find articles despite misspelled queries, ranked by title and tag relevance.
Contact and directory lookup
Find people by approximate name, team or role.
Learning search relevance
The strictness slider is a hands-on way to understand how fuzzy thresholds behave.

Got questions?

Frequently Asked Questions

Start around 0.3. Lower is stricter and returns fewer results; higher forgives more typos but adds unrelated matches. Tune it against real queries.

includeScore returns an error value where 0 is a perfect match and 1 is a complete mismatch. This snippet converts it to a relevance percentage.

Each key can have a weight; matches in higher-weighted fields contribute more to the final score, so title hits outrank tag hits.

Without it Fuse prefers matches near the start of a field, which unfairly penalises words later in long product names.

It is fast for a few thousand items in memory. For tens of thousands, index server-side with a search engine.

Escape every string before inserting it as HTML, as the highlight function does, or build DOM nodes with textContent.

Yes. Use the JSX, Vue, Angular or Tailwind export buttons on this page to convert the markup and styles. The behaviour comes from Fuse.js, so in a framework project install it with npm install fuse.js instead of the CDN tag, build the index with useMemo / computed / a service, keyed on the data, and release it with nothing (it holds no DOM listeners) when the component unmounts.