While migrating from a Wordpress site to a static site in Hugo, I needed to implement some kind of search to replace the search available in the dynamic Wordpress site. There were several articles written about how to do this using the lunr.js search framework but I couldn’t get some of them to work very well so decided to write this post in case anyone else is having similar trouble.
The main idea is to generate a searchable index based on the current state of the site and then that index is used by lunr.js at runtime in the browser to execute the search.
Generating the Search Index
This step is performed after generating the site in Hugo. A script file is run from Node and the console output is redirected to a search-index.json file in the static folder via this command:
node ./build-lunrjs-index.js > static/gen/search-index.json
The generation has to be run each time content is changed or added so that the search-index.json can be uploaded for use in the search.
Implementing the Search Form
This part was the more confusing aspect as I had issues getting the search form to work and even where to put the search form. I finally figured out the search form could be put in a directory called layouts/_default and the content and processing goes into the search.html file in that directory. The layout concept allows it to be independent of the themes while integrating well with the content.
Then a search content page was added as index.md in a directory called content/search:
--- layout: search title: Search permalink: /search/ noToc: true menu: main ---
The layout: search line ties it to the search.html layout and the menu: main line ensures that there will be a search reference in the main menu.
The complete site can be found at this repository.