Fuzzy Searching with Astro.js

Arlind Musliu cofounder at Lucky Media
Arlind Musliu

March 19, 2026 · 4 min read

Fuzzy Searching with Astro.js

Fuzzy search is a clever approach that finds matches even when your search terms aren’t perfect. Ever mistyped something while conducting an online search but still received the correct results? That’s the magic of fuzzy search at work! It’s like having a friend who knows exactly what you mean, even when you don’t say it right.

In this blog post, we’ll explore fuzzy search and how you can use it with Astro.js and Fuse.js.

Fuzzy Search example

Think of fuzzy search as an insightful guide who understands your needs even if you misremember the details. By using sophisticated techniques, fuzzy search can interpret your intentions, making it easier to locate what you’re seeking. For instance, if you intend to find information on The Great Gatsby but mistakenly input The Great Gtasby, the fuzzy search algorithm could still direct you to F. Scott Fitzgerald’s classic novel.

Fuzzy Search example

Fuzzy logic meaning

Unlike traditional logic that deals with black-or-white, yes-or-no decisions, fuzzy logic accommodates the gray areas. It mimics human thought processes, using approximative reasoning to enhance decision-making complexity. This nuanced approach allows fuzzy search to interpret your intentions, making it easier to locate what you’re seeking.

Astro.js with Fuse integration

We’ll be using Fuse.js, a lightweight JavaScript library for fuzzy searching, and Astro.js, a modern static site generator. This combo is ideal for those favoring minimalistic yet efficient solutions.

Fuse.js offers powerful search capabilities, and integrating it with Astro.js can be a game-changer for your search functionality. Depending on your technical comfort level, you can choose from two approaches: using a UI framework or plain JavaScript.

Choosing the right approach for fuzzy searching

Choosing the right approach

Here’s a quick comparison to help you decide which method suits you best:

Approach

Core Idea

Best for

UI Framework

Create an interactive component (e.g., React) to handle the search.

Developers already using a UI framework who want a reactive, component-based architecture.

Vanilla JavaScript

Use a plain JavaScript script inside an Astro component to handle the search logic.

Those preferring a lightweight, framework-free solution with minimal bundle size.

Using a React component

This method is ideal if you are already working with React in your Astro project.

Install the required dependencies:

npm install fuse.js react react-dom

This will add:

  • fuse.js for fuzzy search

  • react and react-dom for the interactive search component

Create a static endpoint

First, create an API endpoint in your src/pages directory (e.g., all-content.json.js) that serves your site's content as JSON. This data will be used to build the search index.

// src/pages/all-content.json.js
import { getCollection } from 'astro:content';

export const GET = async () => {
  const posts = await getCollection('posts');
  const searchData = posts.map((post) => ({
    title: post.data.title,
    description: post.data.description,
    slug: post.slug,
  }));
  return new Response(JSON.stringify({ search: searchData }));
};

Build the React search component

Create a React component (e.g., Search.jsx) that uses Fuse.js:

// src/components/SearchComponent.jsx
import Fuse from 'fuse.js';
import { useState } from 'react';

// Configure Fuse.js
const options = {
  keys: ['title', 'description'], // Fields to search in
  includeMatches: true,
  minMatchCharLength: 2,
  threshold: 0.3, // Adjust for fuzziness sensitivity
};

export default function SearchComponent({ data }) {
  const [query, setQuery] = useState('');
  const fuse = new Fuse(data, options);
  const results = fuse.search(query);
  const searchResults = query ? results.map(result => result.item) : [];

  const handleOnSearch = ({ target }) => {
    setQuery(target.value);
  };

  return (
    <div>
      <input 
        type="text" 
        value={query} 
        onChange={handleOnSearch} 
        placeholder="Search posts..." 
      />
      <ul>
        {searchResults.map((post) => (
          <li key={post.slug}>
            <a href={`/${post.slug}`}>{post.title}</a>
            <p>{post.description}</p>
          </li>
        ))}
      </ul>
    </div>
  );
}

Use the component in an Astro page

Integrate the component into your Astro page. Use the client:load directive to ensure it's hydrated and interactive.

---
// src/pages/search.astro
import SearchComponent from '../components/SearchComponent';
const response = await fetch(`${import.meta.env.PROD ? 'https://your-production-url.com' : 'http://localhost:4321'}/all-content.json`);
const { search: data = [] } = await response.json();
---

<SearchComponent client:load data={data} />

Using Vanilla JavaScript

For a simpler, framework-free solution, you can use a plain JavaScript script inside an Astro component.

Create the data endpoint

Create an API endpoint in your src/pages directory (e.g., all-content.json.js) that serves your site's content as JSON. This data will be used to build the search index.

// src/pages/all-content.json.js
import { getCollection } from 'astro:content';

export const GET = async () => {
  const posts = await getCollection('posts');
  const searchData = posts.map((post) => ({
    title: post.data.title,
    description: post.data.description,
    slug: post.slug,
  }));
  return new Response(JSON.stringify({ search: searchData }));
};

Build the Astro component

Create a component (e.g., Search.astro) that includes the HTML form and the search logic.

<!-- src/components/Search.astro -->
<form id="searchForm">
  <label for="searchInput">Search</label>
  <input type="text" id="searchInput" placeholder="Search..." />
</form>
<div id="searchResults"></div>

<script>
  import Fuse from 'fuse.js';

  (async function () {
    // Fetch the search data
    const response = await fetch('/all-content.json');
    const { posts } = await response.json();

    // Initialize Fuse.js
    const fuse = new Fuse(posts, {
      keys: ['title'],
      threshold: 0.3,
    });

    const searchInput = document.getElementById('searchInput');
    const resultsContainer = document.getElementById('searchResults');

    searchInput.addEventListener('input', (e) => {
      const query = e.target.value;
      const results = fuse.search(query);
      const searchResults = results.map(result => result.item);

      // Update the DOM with results
      resultsContainer.innerHTML = searchResults.map(post => 
        `<article><a href="${post.slug}">${post.title}</a></article>`
      ).join('');
    });
  })();
</script>

The behavior of the fuzzy search is controlled by the options object you pass to Fuse.js. Here are key options to adjust:

  • keys: The object properties to search in (e.g., ['title', 'description', 'body']).

  • threshold: A number between 0 and 1. A lower value (e.g., 0.2) makes the search less fuzzy and requires closer matches. A higher value (e.g., 0.6) makes it more forgiving.

  • minMatchCharLength: The minimum number of characters that must be matched (e.g., 2).

  • ignoreLocation: Setting this to true is useful if you want matches anywhere in the string to be considered equal, regardless of where the pattern is found.

Conclusion

Whether you choose the React or Vanilla JS method, the core principle remains the same: pre-render your data as JSON and let Fuse.js work its magic in the browser. By combining the power of fuzzy search with Astro.js, you can create a user-friendly search experience that understands and adapts to human error.


Build your Astro site for SEO from day one

Every Astro site we build at Lucky Media ships with clean structured data, full Core Web Vitals optimization, automatic sitemaps, and the headless CMS setup that gives your marketing team full content control. We are an Official Astro Partner.

Lucky Media is proud to be recognized as a leading Astro development agency.

FAQs

What is the main advantage of using Fuse.js with Astro.js?

Fuse.js provides powerful fuzzy search capabilities, while Astro.js offers a modern, efficient way to build static sites. Together, they enable developers to create highly responsive search features with minimal overhead.

Can I use Fuse.js with other frameworks besides Astro.js?

Absolutely! Fuse.js is a versatile library that can be integrated with various frameworks like React, Vue, or even plain JavaScript.

How do I optimize the performance of a fuzzy search?

Fine-tuning parameters like threshold, keys, and minMatchCharLength in Fuse.js can significantly impact search performance and accuracy. Experimenting with these options will help you find the right balance.

Is it possible to extend fuzzy search to include more complex data types?

Yes, Fuse.js can handle complex data structures. You can specify nested keys in the options object to search within nested data.

Do I need an internet connection to use Fuse.js?

No, Fuse.js operates entirely client-side, so once the library and data are loaded, it can function offline, making it ideal for static site environments.

Technologies

Astro
Arlind Musliu cofounder at Lucky Media
Arlind Musliu

Cofounder and CFO of Lucky Media

Stay up-to-date

Be updated with all news, products and tips we share!

Let’s chat

We partner with a limited number of brands each quarter to ensure senior-level attention on every project.

lokman and arlind headshots
Teamwork