Skip to content
FLAVIO COPES
flaviocopes.com
2026

How I added search to my static site with Pagefind

By Flavio Copes

How I added fast client-side search to my static Astro blog with Pagefind, which indexes your HTML at build time and runs entirely in the browser.

~~~

This blog has over 1700 posts and, until recently, no search.

The problem with search on a static site is that there’s no server to run the query. I didn’t want to add a backend, or pay for a hosted search service, just for this.

Pagefind solves it. It indexes your HTML after the build, and the search runs entirely in the browser.

How Pagefind works

You build your site as usual. Then Pagefind reads the generated HTML and builds a search index, split into small chunks.

When someone searches, the browser downloads only the chunks it needs. So even with thousands of pages, a visitor downloads a few kilobytes, not the whole index.

No server. No database. No monthly bill.

Installing it

Install Pagefind as a dev dependency:

npm install -D pagefind

Then run it after your build, pointing it at your output folder. On my Astro site the output is dist:

{
  "scripts": {
    "build": "astro build && pagefind --site dist"
  }
}

Now every build creates a dist/pagefind/ folder with the index and a ready-made search UI.

Pagefind ships a UI you can drop in. I made a /search page with an empty container and loaded the UI into it:

<link href="/pagefind/pagefind-ui.css" rel="stylesheet" />

<div id="search"></div>

<script src="/pagefind/pagefind-ui.js"></script>
<script>
  window.addEventListener('DOMContentLoaded', () => {
    new PagefindUI({ element: '#search' })
  })
</script>

That’s a full search page. Type a word and results show up as you type.

Searching only your content

By default Pagefind indexes the whole page, including your header and footer. That’s noisy: every page ends up matching the words in your nav.

The fix is one attribute. Add data-pagefind-body to the element that holds your actual content:

<article data-pagefind-body>
  <!-- the post -->
</article>

Once any page uses data-pagefind-body, Pagefind only indexes those regions, and skips pages that don’t have it. So my search returns posts, not menu items.

One thing to watch

Pagefind runs on the built site, so it doesn’t work in the dev server. The index doesn’t exist until you build.

To test it locally, build first, then preview:

npm run build
npm run preview

That’s the whole setup, and it costs nothing to run.

Tagged: Astro · All topics
~~~

Related posts about astro: