Fuse JS and Alpine JS powered search

Learn how to create a fast, client-side search functionality for your website using Fuse.js and Alpine.js. This tutorial shows you how to implement fuzzy search capabilities with a responsive user interface - perfect for filtering blog posts, products, or any collection of items. The solution requires minimal setup and runs entirely in the browser without any backend dependencies.

Fuse JS Search

Fuse JS is a light weight but powerful javascript library that can be implemented as a fuzzy-search back end. It is fast and has no other dependencies so it's an ideal candidate to be paired with Alpine JS. You can follow their website for more details, here we will create a very basic setup for a blog article search.

Import the library in your head tag.

<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>

Alpine JS Interface

Alpine JS can be used to create an interface for the user to enter their search terms and then displaying the search results list. This is all very easy with Alpine JS.

Import the library in your head tag just like before. You can add it right after Fuse.

<script src="https://cdn.jsdelivr.net/npm/[email protected]"></script>
<script src="//unpkg.com/alpinejs" defer></script>

And then create the interface section in your body tag where ever you need it placed. The class you see uses bootstrap css for making it all look nice.

<div x-data="search()" class="pt-4">
    <div>
        <h5>Search Articles:</h5>
        <input
            type="text"
            placeholder="What are you looking for?"
            class="form-control mb-4"
            @input.debounce="searchArticles"
            x-model.fill="searchTerm"
        />
    </div>
    <div class="row">
        <template x-for="result in results" :key="result.refIndex">
            <div class="col-md-3 mb-3">
                <a
                    :href="`/blog/${result.item.slug}`"
                    x-text="result.item.Title"
                ></a
                ><br />
                <span x-text="result.item.Description"></span>
            </div>
        </template>
    </div>
</div>

And finally we need to put the Javascript logic in place to, set up search and trigger on a usr interaction. As the user starts typing, once the string is over a few characters, the search will dynamically update and display the results. Feel free to use the Fuse website to adjust the search options. The list is the list of articles that will be searched. In this example we used php to build the list and now we are just dumping it directly to be used by the search script.

<script>
    const fuseOptions = {
      keys: ['Title', 'Description', 'slug']
    };
    const list = <?= json_encode($blogItems) ?>;

    function search() {
      return {
        fuse: new Fuse(list, fuseOptions),
        searchTerm: '',
        results: [],
        searchArticles() {
          if (this.searchTerm.length < 4) {
            this.results = [];
          } else {
            this.results = this.fuse.search(this.searchTerm);
          }
        }
      };
    };
</script>

Here is an example of how the list object may look like.

const list = [
    {
        Title: "Fuse JS and Alpine JS powered search",
        Description:
            "A tutorial on setting up a Fuse JS powered search with an Alpine JS driven UI",
        slug: "alpinejs-fusejs-search",
    },
    {
        Title: "Using CakePHP with Bootstrap 5",
        Description:
            "A quick guide on how to create a great email templates with MJML and use them in CakePHP",
        slug: "cakephp-bootstrap",
    },
];

And that is all it takes to implement Fuse JS search with an Alpine JS front end. Using Alpine JS makes it really easy to turn parts of your website into dynamic content while still allowing you to take advantage of technologies like CloudFlare and caching for a performant website that can handle millions of views lightning fast. Here is a guide to cloudflare static website caching if you want to learn more.

Next Article: Blog by Blue Leaf

Comments or questions?

Please contact us! We are excited to hear from you.