Published on 24 July 2024

5 min read

901 words

Adding Fuzzy Search to Your Static Website with Fuse.js

Learn how to add fuzzy search to your static website using Fuse.js. This tutorial will guide you through the process of integrating a search feature that provides relevant results to users.

JavascriptReactTypeScript
Cover image for Adding Fuzzy Search to Your Static Website with Fuse.js

Adding a search feature to a static website can be challenging but luckily there are some great tools out there that can help. In this article, I will be using Fuse.js, a small fuzzy search library with zero dependecies. On a normal website, you would have a backend server with an API route to handle the search. If you are using a CMS (Content Management System), they ususally have a way to implement search via their API. If you’re dataset is small, using a fuzzy search library like Fuse.js is a great option.

For this article, I am going to use React, Tailwind and Typescript but you can use any frontend framework or library you like.

Installation

To get started, you will need to install Fuse.js.

Terminal window
1
npm install fuse.js

User Interface

Initial search component with static data

Let’s build the search component with just some static HTML. The list for now will be a static list.

Search.tsx
1
export default function Search() {
2
return (
3
<div className="mt-2">
4
<input
5
name="search"
6
type="text"
7
placeholder="Search for games"
8
className="block w-full rounded-md border-2 p-2 py-1.5 text-sm leading-6 text-slate-900 shadow-sm placeholder:text-slate-400"
9
/>
10
<ul className="mt-4 rounded-md border bg-slate-100 p-4">
11
<li className="my-2">Game 1</li>
12
<li className="my-2">Game 2</li>
13
<li className="my-2">Game 3</li>
14
</ul>
15
</div>
16
)
17
}

Adding state to the search component

Nice! We have our initial search component with some basic HTML and static data. Now let’s add some state to the component to handle the search input.

We need an event to fire when the user types into the input field. I will store what the user types in a state variable called query. Let’s make the function handleSearch to handle the input change. Your updated component should look like this:

Search.tsx
1
import { useState } from 'react'
2
3
export default function Search() {
4
const [query, setQuery] = useState<string>('')
5
6
const handleSearch = (value: string) => {
7
setQuery(value)
8
}
9
10
return (
11
<div className="mt-2">
12
<input
13
value={query}
14
onChange={({ target: { value } }) => handleSearch(value)}
15
name="search"
16
type="text"
17
placeholder="Search for games"
18
className="block w-full rounded-md border-2 p-2 py-1.5 text-sm leading-6 text-slate-900 shadow-sm placeholder:text-slate-400"
19
/>
20
21
<ul className="mt-4 rounded-md border bg-slate-100 p-4">
22
<li className="my-2">Game 1</li>
23
<li className="my-2">Game 2</li>
24
<li className="my-2">Game 3</li>
25
</ul>
26
</div>
27
)
28
}

Adding Fuse.js to the search component

Now that we have our search component working with state, let’s add Fuse.js to our component. I will use Fuse.js to search through the list of games and filter the results based on the user’s input. The final component should look like this:

Search.tsx
1
import { useState } from 'react'
2
import Fuse, { type FuseResult } from 'fuse.js'
3
4
type Game = {
5
title: string
6
system: string
7
genre: string
8
}
9
10
const games = [
11
{
12
title: 'The Legend of Zelda: Breath of the Wild',
13
system: 'Nintendo Switch',
14
genre: 'Action-adventure'
15
},
16
{
17
title: 'Super Mario Odyssey',
18
system: 'Nintendo Switch',
19
genre: 'Platformer'
20
},
21
{
22
title: 'Halo Infinite',
23
system: 'Xbox Series X',
24
genre: 'First-person shooter'
25
},
26
{
27
title: 'God of War',
28
system: 'PlayStation 4',
29
genre: 'Action-adventure'
30
},
31
{
32
title: 'The Last of Us Part II',
33
system: 'PlayStation 4',
34
genre: 'Action-adventure'
35
}
36
] as Game[]
37
38
export default function Search() {
39
const [query, setQuery] = useState<string>('')
40
const [results, setResults] = useState<FuseResult<Game>[]>([])
41
42
const handleSearch = (value: string) => {
43
const fuse = new Fuse(games, {
44
keys: ['title', 'system'],
45
includeScore: true,
46
isCaseSensitive: false,
47
includeMatches: true,
48
threshold: 0.5,
49
minMatchCharLength: 2
50
})
51
const searchResult = fuse.search(query)
52
53
setResults(searchResult)
54
setQuery(value)
55
}
56
57
return (
58
<div className="mt-2">
59
<input
60
onChange={({ target: { value } }) => handleSearch(value)}
61
name="search"
62
type="text"
63
placeholder="Search for games"
64
className="block w-full rounded-md border-2 p-2 py-1.5 text-sm leading-6 text-slate-900 shadow-sm placeholder:text-slate-400"
65
/>
66
67
{results.length > 0 && (
68
<ul className="mt-4 rounded-md border bg-slate-100 p-4">
69
{results.map((result) => (
70
<li key={result.item.title} className="my-2">
71
{result.item.title}
72
</li>
73
))}
74
</ul>
75
)}
76
</div>
77
)
78
}

We added an array of games that will work as our dataset as a simple example. We then created a new instance of Fuse inside the search function with some options.

Here are what each option does here:

  • keys: The keys to search in the dataset. We are searching in the title and system keys.
  • includeScore: Whether to include the score in the result
  • isCaseSensitive: Whether the search is case sensitive
  • includeMatches: Whether to include matches in the result
  • threshold: The threshold to consider a match. 0.0 is perfect match and 1.0 is match anything
  • minMatchCharLength: The minimum number of characters to match

The list was updated to show the results of the search. If there are no results, the list will not be shown. The search function was also updated to call the search method from Fuse. You might have to adjust the Fuse.js options to fit your needs.

Conclusion

That’s it! You now have a fuzzy search feature on your static website using Fuse.js. You can now search through the list of games and filter the results based on the user’s input. Remember that this is only suitable for smaller datasets, always use an API if you are working with large datasets. Feel free to customize the search component to fit your needs.

Resources

Fuse.js

Ready to start your project?
Boost your online pressence today.

We can make your brand look online without breaking the bank. Your website is the first impression you make on your customers. Make it count.

Our work

When we build websites for our clients, we believe in delivering high quality work that is accessible, performant and easy to use.

What our clients said

"Mary with Space City Web Designs is amazing! Her communication is outstanding and she makes sure you love everything about your website. If there is anything you don't like, they will fix it immediately! The website is everything I have thought of. Working with Mary was great and I highly recommend Space City Web Designs."

Whitney Evans
Owner of Paw Balm by KW Walkers

"Space City Web Designs was easy to work with. My finished website looked very professional. I am very happy with the end result."

Jessica Will
Owner of CW Enterprises

About Us

Owned by a married couple in Houston, TX, we are a small business just like you. We are experienced software engineers with over a decade of industry experience building web applications for companies. We are passionate about helping small business with their technological needs.

Downtown Houston, Texas