Adding search to a static Jekyll site using pagefind
Suprisingly, I’ve managed to keep writing here on and off, and when I saw Pagefind I thought it looked like a great way to add search to my static site. It was refreshing easily!
I use Jekyll to build this blog - it outputs all the html for the site into a folder called _site
and to deploy it, I rsync up the changes to my host.
Pagefind works by indexing all your html content and creating some additional files in the root of your static site. It creates a _pagefind
directory and in there are the js files needed for the search UI to work on your site, plus the search indices and meta files it creates.
Put a UI placeholder somewhere in the navigation section of your Jekyll template:
<div id="search"></div>
Hook up the JS near the bottom of your html:
<script src="/_pagefind/pagefind-ui.js" type="text/javascript"></script>
<script>
window.addEventListener('DOMContentLoaded', (event) => {
new PagefindUI({ element: "#search" });
});
</script>
</body>
</html>
Add the pagefind css too if you want (I’ve omitted it, because I’ll style it differently at some point):
<head>
<link href="/_pagefind/pagefind-ui.css" rel="stylesheet">
and then once you’ve built the latest version of your site with jekyll build
, call pagefind, pointing it at your built root:
pagefind --source _site
The Pagefind CLI page shows you the various options you can use.
If you save the options you want in a pagefind.yml
file, you can call pagefind
with no options.
Here’s my pagefind.yml
force_language: en
source: _site
glob: "*[!s]/**/*.{html}"
bundle_dir: _pagefind
exclude_selectors:
- "#links"
- "#recent-posts"
- "footer"
I set English as the only language and point to the Jekyll _site
folder.
The glob
setting is telling pagefind to index any .html
file in any folder, except those that are in a folder ending with s
. This is because Jekyll generates a tags
directory which pagefind was indexing and causing duplicate results to appear; one from the page with the blog post on, and the duplicate entry from the tags
directory.
I wrote about this in an open Pagefind issue about the glob option. It works for me because I only have the one folder tags
that ends in s
. If you have e.g. a cats
folder that you do want pagefind to index, then this won’t work for you.
bundle_dir
tells pagefind where to save its assets and search index files. exclude_selectors
is a set of css selectors that I don’t want pagefind to index the content from, largely to avoid duplicate or unecessary results.
Pagefind can serve your built site if you call pagefind --serve
- you can’t get Jekyll to do it, because it will overwrite your _pagefind
folder. Once you’re happy with everything, publish your site to your host.
All links, in order of mention:
- Pagefind: http://pagefind.app/
- Jekyll: https://jekyllrb.com
- rsync: https://rsync.samba.org
- Pagefind CLI page: https://pagefind.app/docs/config-options/
- Pagefind issue about the glob option: https://github.com/CloudCannon/pagefind/issues/128#issuecomment-1620123795
- css selectors: https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors
Recent posts:
- Patch for aarch64 (aka arm64) openssl 1.0.2 'relocation R_AARCH64_PREL64 against symbol OPENSSL_armcap_P error'
- TIL: the `NO_COLOR` informal standard to suppress ANSI colour escape codes
- Copy the contents of a branch into an existing git branch without merging
- asdf, python and automatically enabling virtual envs
- Clink makes working with Windows' `cmd.exe` so much nicer