Adding search to Jekyll using pagefind

I don’t do many blogs-about-blogging here but this is something I’ve been hoping to do for a while, and man I have to say that Pagefind1 made setting up search a breeze on this site. There’s no database, no third party - just static files!
Pagefind is a program you run after your whole site is built. In this article I want to cover how to automate this final step in the website build, without using npm or extra ruby gems etc.
Everything else like styling and tweaking the results can be found on the pagefind docs.
How I did it
Download pagefind
First, download the standalone binary from the pagefind releases2 page. There are a few to choose from.
Extract the file and move the binary (in my case it was just called pagefind
) to your Jekyll website. I put mine in a folder called _bin
.
I like this because it means not having to use node, which is always a plus in a ruby project.
Setup jekyll plugin
Create the following file in the _plugins
directory in the root of your jekyll site (I called mine pagefind.rb
):
module Jekyll
class PostCompileCommand < Jekyll::Generator
safe true
priority :lowest
def generate(site)
Jekyll::Hooks.register :site, :post_write do |_site|
command = './_bin/pagefind --site _site'
puts "Running: #{command}"
system(command)
end
end
end
end
Continue with setup from docs
Then you do what the website says3. Create a <div id="search">
, add the stuff in your <head>
, set up the js script etc etc.
At this point, you’re off! When you build your jekyll site, at the end of the process the little plugin will build the pagefind index for you. A search box appears where you put the <div>
.
Tailoring this to my website
There are a few tweaks I made here and there in case you are interested:
- Set up a fallback for people with no javascript enabled (search is disabled)
- Tweaked the design to match my website (very easy to override some parts in your css, without doing the whole thing - see their docs for this)
- Set up the index to only scan blog posts (very easy to do, see the docs)
- Added weights to bits of metadata (again easy to do)
Advantages
- Lightweight
- No database
- No third party service
- No dependencies
- Fast
- Pretty
- Not a total headache to get up and running
- Easy to tweak the index through html attributes
Drawbacks
- I prefer no-js but I think it’s worth it here.
- I have commited the binary to my repository. It’s quite small but this does feel like a weird thing to do (but it also makes it easy to push this to netlify with no fuss).
- You have to keep the pagefind binary updated yourself (I just use the RSS feed) if you are interested in updates. But, if it works now for you it should just continue working, particularly with this standalone binary approach.