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.
-
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 multipledata-pagefind-body
attributes as any element with this element will be combined in the index. -
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 apagefind.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.
Element | Ranking |
---|---|
h1 | 7.0 |
h2 | 6.0 |
h3 | 5.0 |
h4 | 4.0 |
h5 | 3.0 |
h6 | 2.0 |
All other elements | 1.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:
Option | Default | Type | Note |
---|---|---|---|
element* | n/a | string | HTML element to build UI in |
showSubResults | false | boolean | show nested results |
showImages | true | boolean | include images with results |
exerptLength | 30 | number | maximum length for excerpts |
processTerm | n/a | function | runs before performing a search |
processResult | n/a | function | runs before showing a result |
showEmptyFilters | true | boolean | show/hide no remaining results |
resetStyles | true | boolean | default css reset (true) or your site’s (false) |
bundlePath | bundle path | string | relative path to final pagefind dir |
debounceTimeoutMs | 300 | number | number of ms to wait before searching |
translations | n/a | object | custom 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!