Harmonic Notes on General Topics

Occasional announcements and posts not specific to horn, MATLAB, or image processing

« Website Changes...

Adding Search Using Pagefind

Steve Eddins
July 30, 2025

Contents

I have been content with my return to using Hugo, a static site generator, to create and maintain this site. One feature that I temporarily lost, though, with the move away from Ghost Pro, was search. I’m up to 63 posts posts on the site now. Even if none of my readers needs to search on the site, I do.

The Hugo documentation lists open-source and commercial tools that can be used to add search to a Hugo-based site. I looked over the possibilities and decided to try pagefind.

It turned out to be pretty easy to get pagefind working. There were just a few changes needed.

Build the index

One requirement is to tell my deployment host, Vercel, to add an indexing step to the build procedure. It looks like this:

hugo --gc; npx -y pagefind --site public

The first command, hugo --gc, is the normal Hugo build step. The second command, npx -y pagefind --site public, runs pagefind, which indexes the just-built site and places the index files into a pagefind subdirectory.

Identify the parts to be indexed

Pagefind will, by default, index everything that appears on a page, including headers, navigation menus, footers, etc. You can narrow that down by adding some hints to the page HTML. If data-pagefind-body appears anywhere in a tag, as below, then pagefind only indexes material inside tags where it appears.

<main data-pagefind-body>
  {{ .Content }}
</main>

Second, you can help pagefind reliably find page titles like this:

<h1 data-pagefind-meta="title">

Both of those changes can be made in the template that is used to generate every page.

Put a search UI on the site

A search UI provides a way for someone on the site to enter a search term, searches the site index, and then displays the search result. You can roll your own search UI using the pagefind Javascript API, but I was happy enough with the out-of-the-box search UI that comes with pagefind. I created a search page and included the sample pagefind UI code on it:

<link href="/pagefind/pagefind-ui.css" rel="stylesheet">
<script src="/pagefind/pagefind-ui.js"></script>
<div id="search"></div>
<script>
    window.addEventListener('DOMContentLoaded', (event) => {
        new PagefindUI({ element: "#search", showSubResults: true });
    });
</script>

At this point, I was just looking for the simplest-possible implementation that would be functional. I looked for a way to add a search icon (magnifying class) to the main navigation menu at the top of every page. I settled on using the search icon from the Google’s material symbols font. I added this code to the page head template:

<!-- Web font used for the search icon -->
<link href="https://fonts.googleapis.com/css2?family=Material+Symbols+Outlined:wght@400&icon_names=search" rel="stylesheet" />

And I added this item to the main nav menu:

<li><a href="/search/"><span class="material-symbols-outlined">search</span></a></li>

Results

Here is a sample search result. I really like the way that the default pagefind UI displays the search results.

Sample search results