Search | Sailfish OS | Running | PineTime | All Posts

Installing Pagefind, a static search engine, on FreeBSD

January 23, 2023 — Nico Cartron

I finally have a search feature on my blog - here's how I implemented it.


The Need

As my number of blog articles kept growing, I found it more and more annoying not to be able to search for an article or a topic - both for readers, but also for me as I like to link to my own articles when answering to questions on e.g. the Sailfish OS forum, or the PineTime Telegram channel.

I wanted something simple and light, which I could easily tweak and that would be consistent with the rest of my blog.

The Solution I Chose

Tony Finch has himself implemented a search feature on his blog, and he chose Pagefind.

Tony mentioned Pagefind in one of his tweet back in July 2022, so as you can see, it took me a bit of time to deploy it myself ;)

Installing Pagefind

Compatible Operating Systems

My webserver runs (of course) on one of my FreeBSD VMs, so I had to install Pagefind on it.

The installation instructions mention that Linux, MacOS and Windows are supported OS, but FreeBSD is nowhere to be found.

Installing on FreeBSD

So I had to install it myself, and since I didn't want to use npx, building from source was the remaining option.

Here's what I did:

  1. Install Rust and Cargo (the Rust package manager):

    pkg install rust
    pkg install cargo-generate

  2. Check whether pagefind exists:

    cargo search pagefind

    => Updating crates.io index
    pagefind = "0.10.6" # Implement search on any static website.
    pagefind_stem = "0.2.0" # Snowball stemming algorithms repackaged for Rust, with languages behind feature flags.

  3. Install Pagefind:

    cargo install pagefind

    ... which gave me that error message:

    error: failed to download `pagefind v0.10.6`

    Caused by:
    failed to enable HTTP2, is curl not built right?

    Caused by:
    [1] Unsupported protocol

    Alright, the curl I had on my FreeBSD did not support HTTP/2, let's fix that:

    • make deinstall curl
    • make config -> select HTTP/2
    • make install

    Trying again, this time it worked but still stopped on that error:

    error[E0658]: `let...else` statements are unstable
    --> /root/.cargo/registry/src/github.com-1ecc6299db9ec823/pagefind-0.10.6/src/fossick/mod.rs:212:5
    [...]
    = note: see issue #87335 <https://github.com/rust-lang/rust/issues/87335> for more information
    = help: add `#![feature(let_else)]` to the crate attributes to enable

Forget pkg, let's try with FreeBSD ports

Looks like pkg was not with me, so I removed the rust and cargo packages:

pkg remove rust-nightly
pkg remove cargo-generate

and then installed the Rust's port:

cd /usr/ports/lang/rust
make config
make install

and did the same with Cargo - I could then install Pagefind!

Running pagefind

From CLI

I first ran Pagefind from the command line:

$ pagefind --source "/usr/local/www/nico"

Running Pagefind v0.10.6
Running from: "/~/scripts"
Source: "/usr/local/www/nico"
Bundle Directory: "_pagefind"
[...] [Building search indexes]
Total:
Indexed 1 language
Indexed 152 pages
Indexed 10065 words
Indexed 0 filters
Indexed 0 sorts
Finished in 0.517 seconds

It created a _pagefind directory.

All I had to do afterwards was creating an HTML page with a piece of script to call Pagefind - an example is provided on Pagefind's webpage:

<div id="divbody"><div class="content">
<link href="/_pagefind/pagefind-ui.css" rel="stylesheet">
<script src="/_pagefind/pagefind-ui.js" type="text/javascript"></script>
<div id="search"></div>
<script>

Tweaking Pagefind

Returned results are OK, but titles are off:

That's because PageFind uses the first H1 tag it sees, which in my case is "Nico's Blog".

This can be overriden (see the doc), so in my case, I want to use TITLE, so I had to modify the BashBlog script to insert data-pagefind-meta="title" as part of the title tag.

The magic of opensource :-)

Then the result:

Cron script

OK, now let's run Pagefind every day, adding this line in the crontab:

0 5 * * * /home/nico/scripts/pagefind.sh >/dev/null 2>&1

By default, Pagefind will look at a pagefind.yml configuration file in the same directoy - I created it with:

source: /usr/local/www/nico/
bundle_dir: /usr/local/www/nico/_pagefind

Wrap Up

I'm super happy to now have a Search feature on my Blog, not only for visitors, but also for me, as I was quite often searching for some of my articles to send links e.g. on Twitter, and that avoids me having to grep on my local filesystem :)

This also confirms my choice to stick to BashBlog and flat files that I can easily modify!


Tags: FreeBSD, Geek


I don't have any commenting system, but email me (nicolas at ncartron dot org) your comments!
If you like my work, you can buy me a coffee!