Pagefind is a new fully static search library by the amazing team over at CloudCannon.

It’s very fast due to a few factors:

  • built in Rust (what isn’t these days!)
  • splits the search index into chunks
  • loads only required chunks per search

By default, Pagefind includes:

  • a default UI
  • multilingual support
  • filtering and searching
  • a full API to roll your own custom search
  • customization options for functionality and styling

It’s a perfect match for Astro.

Installation

Install package

You can either install it, or just run everything through npx. I’ll install it locally to my project.

Install command: npm i -D pagefind

Add head tags

Remember to add “is:inline” in Astro to tell Astro to not bundle the script.

<link href="/pagefind/pagefind-ui.css" rel="stylesheet" />
<script src="/pagefind/pagefind-ui.js" is:inline></script>

We’ll remove these later when generating our own UI.

Usage

Pagefind includes a built-in UI, which you can customize.

Add the Built-in UI

Create a Search.astro component and add the following:

<div id="search"></div>
<script>
  window.addEventListener("DOMContentLoaded", (event) => {
    new PagefindUI({ element: "#search", showSubResults: true });
  });
</script>

Note: If using ViewTransitions, add a transition:persist directive to the div.

Index your site

You’ll need to build your site and then run a script to create the search index. The two script we need to run are npm run build and pagefind --site dist.

To simplify things, I’ll update the build script in my package.json file to include both commands.

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

Run the build command to both build and index your site.

Note: Since the linked css and js reference your build folder, dev mode will throw errors, as it’ll look into your public folder. So I’d recommend copying the generated pagefind directory to your public folder after it’s generated. You can modify the build script to the following: astro check && astro build && pagefind --site dist && cp -r dist/pagefind public/. Astro will use the pagefind data from your last build during dev mode.

Preview the results

To preview the changes, run your preview command (npm run preview by default).

Astro will spin up port 4321. The default Pagefind UI generates a search input and returns results with images where possible.

Customizing Pagefind’s Index

You can customize the index, weight, and more. You can also create your own UI, but I’ll leave you to explore the documentation, as the default UI gives you so much out-of-the-box.

Choose what is indexed

By default, Pagefind indexes everything inside of your <body> tag. You can choose what is indexed in two ways.

  1. Add element(s) to the index. Add data-pagefind-body to any element on any page in your site. Now only this element will be indexed by Pagefind. You can add multiple data-pagefind-body attributes as any element with this element will be combined in the index.

  2. Remove element(s) from the index. Add data-pagefind-ignore to explicitly remove an element and its children from the search index. While there are some additional configuration options for metadata, generally speaking, Pagefind will ignore this element. If removing specific selectors all throughout your site, consider using a pagefind.yml file with a custom list of excluded selectors.

Note: You can also add individual elements as metadata to be indexed. Learn more about adding metadata to your search index.

Set a custom search weight

Pagefind an rank any indexed item from 0.0 to 10.0. Here are the default rankings.

ElementRanking
h17.0
h26.0
h35.0
h44.0
h53.0
h62.0
All other elements1.0

Add custom ranking with the data-pagefind-weight attribute, providing the rank as the value.

<p data-pagefind-weight="2">
  This is very important and should be ranked higher.
</p>

Note: Weightings are ranked using a quadratic scale, so a ranking of 2.0 will have roughly 4 times the impact of standard text, and a weighting of 10.0 will have roughly 100 times the impact.

Customize Search UI

You can customize the existing UI or roll your own.

Customize the Existing UI

You can customize the returned results as well as the CSS.

To customize the UI, pass your desired options into your PagefindUI instance. Here are the available options:

OptionDefaultTypeNote
element*n/astringHTML element to build UI in
showSubResultsfalsebooleanshow nested results
showImagestruebooleaninclude images with results
exerptLength30numbermaximum length for excerpts
processTermn/afunctionruns before performing a search
processResultn/afunctionruns before showing a result
showEmptyFilterstruebooleanshow/hide no remaining results
resetStylestruebooleandefault css reset (true) or your site’s (false)
bundlePathbundle pathstringrelative path to final pagefind dir
debounceTimeoutMs300numbernumber of ms to wait before searching
translationsn/aobjectcustom strings instead of auto-translations

* required

Example:

new PagefindUI({
  element: "#search",
  debounceTimeoutMs: 500,
  resetStyles: false,
  showEmptyFilters: false,
  excerptLength: 15,
  showImages: false,
  showSubResults: true,
});

Note: For the full defaults for customizing the default UI, view the Default UI config options.

So much more…

The API is quite robust! It comes with out-of-the-box support for:

Each can be customized entirely. And because Pagefind provides access to the underlying APIs for searching, their NodeJS API, the Search API, and more, you can get as custom as you want!