Back to Blog

Building a Search Experience Without Algolia

FlatWP TeamFlatWP Team
2 min read

Algolia is great, but $99/month for search on a small site feels excessive. FlatWP includes a fast, free alternative using static generation and client-side search.

The Static Search Index Approach

We generate a lightweight JSON index at build time:

// app/search-index.json/route.ts
export const revalidate = 3600;

export async function GET() {
  const posts = await fetchAllPosts();
  
  const index = posts.map(post => ({
    id: post.id,
    title: post.title,
    excerpt: post.excerpt,
    slug: post.slug,
    category: post.category.name,
  }));
  
  return Response.json(index);
}

This creates a ~50KB JSON file (for 100 posts) that browsers cache.

Client-Side Search with Fuse.js

Fuse.js provides fuzzy search on the client:

import Fuse from 'fuse.js';

const fuse = new Fuse(searchIndex, {
  keys: ['title', 'excerpt', 'category'],
  threshold: 0.3,
  includeScore: true
});

const results = fuse.search(query);

Search is instant – no network request needed.

When Does This Break Down?

This approach works well up to ~2000 posts. Beyond that:

  • Index size becomes noticeable (~300KB+)
  • Initial download impacts performance
  • Search slowdown on lower-end devices

At that scale, consider upgrading to a search service.

Enhancing the Experience

We add keyboard shortcuts (⌘K), instant results as you type, and proper highlighting:

<Command.Dialog>
  <Command.Input 
    placeholder="Search posts..."
    value={query}
    onValueChange={setQuery}
  />
  <Command.List>
    {results.map(result => (
      <Command.Item key={result.item.id}>
        <Link href={`/blog/${result.item.slug}`}>
          {highlightMatch(result.item.title, query)}
        </Link>
      </Command.Item>
    ))}
  </Command.List>
</Command.Dialog>

Progressive Enhancement

For FlatWP Pro, we’re adding optional Algolia integration. It’s a feature flag:

const searchProvider = process.env.SEARCH_PROVIDER || 'static';

if (searchProvider === 'algolia') {
  // Use Algolia
} else {
  // Use static JSON + Fuse.js
}

Start free, upgrade when needed. No lock-in.

Performance Comparison

We tested search on a 500-post site:

  • Static + Fuse.js: 15ms, 0 network requests
  • Algolia: 45ms average (includes network latency)
  • WordPress search: 300ms+ (full database query)

The static approach is actually faster for most use cases.

FlatWP Team

FlatWP Team

Related Posts