Adding Full-Text Search to an Astro Static Site with Pagefind
Contents
One weakness of static sites is search. Without a server-side backend, you either rely on an external service or build something yourself.
I added Pagefind to this blog, so this is a note on how I did it.
What Pagefind Is
Pagefind is a full-text search library for static sites.
Features:
- Crawls HTML at build time and generates an index
- Splits the index into small chunks so only needed parts are fetched
- Fast search via WebAssembly
- Supports Japanese
- No external service required
Even with 1,000 pages, the initial load stays around a few dozen KB.
Installation
For Astro, there is an integration called astro-pagefind.
pnpm add astro-pagefind @pagefind/default-ui
Add it to astro.config.mjs:
import pagefind from 'astro-pagefind';
export default defineConfig({
integrations: [pagefind()],
// ...
});
Creating the Search Page
---
import BaseLayout from '@/layouts/BaseLayout.astro';
---
<BaseLayout title="Search" description="Search articles">
<main>
<h1>Search</h1>
<div id="search"></div>
</main>
</BaseLayout>
<script>
import { PagefindUI } from '@pagefind/default-ui';
import '@pagefind/default-ui/css/ui.css';
new PagefindUI({
element: '#search',
showSubResults: true,
translations: {
placeholder: 'Search articles...',
zero_results: 'No articles matched "[SEARCH_TERM]"',
},
});
</script>
Customizing the Style
Pagefind’s UI can be customized with CSS variables.
<style is:global>
:root {
--pagefind-ui-scale: 1;
--pagefind-ui-primary: hsl(var(--primary));
--pagefind-ui-text: hsl(var(--foreground));
--pagefind-ui-background: hsl(var(--background));
--pagefind-ui-border: hsl(var(--border));
--pagefind-ui-tag: hsl(var(--secondary));
--pagefind-ui-border-width: 1px;
--pagefind-ui-border-radius: 0.5rem;
--pagefind-ui-font: inherit;
}
</style>
You can reuse the existing design-system variables as-is.
Caveats
It Does Not Work in the Dev Server
Search does not work with pnpm dev. Pagefind’s index is generated during pnpm build.
Use pnpm preview after building to verify it.
Impact on Build Time
Pagefind’s index generation is light. Even a few hundred pages only add a few seconds. It is fine even on Vercel’s free plan.
On this blog (about 80 pages), it took around 0.4 seconds.
Summary
- Install
astro-pagefindand@pagefind/default-ui - Create a search page and initialize PagefindUI
- Customize the style with CSS variables
- Use
pnpm previewwhen testing
Full-text search without an external service is very convenient.