My blog is up and running and I have more than 10 years of content migrated. As part of the migration, I have reviewed categories and tags to ensure that they are consistent, but also to make it easier to find related content.
I can find content based on categories and tags by browsing the pages that list them and the associated pages, but I want to be able to search as well.
How to Search a Static Web App
One of the benfits of using Hugo and an Azure Static Web App is the speed of site. The speed is achieved because all content is “static” meaning that it is generated as raw HTML every time I push a commit to GitHub.
To search this content, I need to index the content after the static content is built and then enable users of the site to search that index and present the results.
To do this there are several options available and they are structured in similar ways:
- Add a JavaScript library that will provide the functionality to search
- Implement a page that interacts with the JavaScript library
I did some basic research on which libraries are most popular, based on the documentation I found, I opted to go with Fuse.js.
Approach
My starting point was the from the Hugo Search page:
Github Gist for Fuse.js integration. This gist demonstrates how to leverage Hugo’s existing build time processing to generate a searchable JSON index used by Fuse.js on the client side. Although this gist uses Fuse.js for fuzzy matching, any client side search tool capable of reading JSON indexes will work. Does not require npm, grunt or other build-time tools except Hugo! >
That sounded perfect! For that don’t know what a GitHub Gist is (and I didn’t), it is a code snippet stored in a repository.
The steps in the Gist were clearly laid out:
- Add a file
content/search.md
which is the file that responds to navigation from the menu - Change the navigation to include a search option pointing to the
content/search.md
file - Add a file
layouts/_default/index.json
- Add a file
layouts/_default/search.html
which will define the contents of the search page - Add a file
static/js/search.js
which manages the search on the page, inlcuding mapping the results to the HTML template inlayouts/_default/search.html
- Make changes to the
config.toml
file
Customisations
This approach worked really well and was really simple to implement.
That being said, I did need to put some effort into really understanding how these files all combine to work together, and I made exetensive changes to my CSS file to make sure I had the outcome that I wanted.
As I learned about the files, I worked out where to make the customisations.
layouts/_default/search.html
This is the key to laying out the search page and, importantly the search results. While the content in this file is limited, the structure of the HTML and the associated styling is where you will need to put effort in to ensure the search results are what you want.
This file needed a bit of tweaking for the references to the javasript libraries:
- JQuery CDN - 3.6.0 works fine and I have not tested higher versions
- mark.js - 8.11.1 works fine and I have not tested higher versions
- fuse.js - v3.2.1 is required, higher versions do not, and I have not tried to make them work
static/js/search.js
This file is created and then tweaked to ensure that the results are mapped back to the correct locations in the HTML template in the layouts/_default/search.html
file.
I delved more into javascript tailoring this file that in any other customisation. The reason for this was to take Cateogries and Tags and replicate the styling that I am using else where in the site.
Outcome
The outcome was a link in the Navigation to a search page that allows you to enter a search term and hit return to search.
The search results are presented with the search term highlighted, the Categories and Tags rendered as they are on the rest of the site and links to get to the post.
And the results are presented lightning fast!