There’s now a search box on this blog! At time of writing, there’s a total of 4 posts to search, but hey, it exists now. Here’s how I made it.
This is a static site. That means there’s no immediately obvious place to run a search algorithm – it can’t really happen in the browser, since that’d require every single post to be downloaded before even starting to search. It can’t really happen on the server, since that’s only serving up pre-made files. So, let’s do it on someone else’s server with a modern serverless design!
I’ve created a Cloudflare Worker which is open source if you’d like to take a look. It’s quite short and sweet, using Fuse.js to handle the search.
The general idea is:
- As part of the build process for this blog, a JSON file is made containing information about all the posts.
- Each time the site is updated, the build system sends a request to the Worker. The Worker retrieves the JSON file of posts and stores the array in Workers KV, a key-value storage system. It also pre-generates the search index and stores that in KV, so it doesn’t need generated for every request. As the number of posts to index grows, this should keep the time to handle each search request a bit lower.
- On the search results page, some frontend JavaScript reads the URL parameters and makes a search request to the Worker. The page is then populated with the results.
I was originally going to replace the content of whatever page you searched on with the results of your query (instead of having a separate page), but that threw up a whole load of usability and accessibility concerns: how do you notify the user the results have appeared? What about on a small screen – do you need to scroll the user to the right part of the page? How do they get back to the page they were on? What about managing keyboard focus? I decided instead of trying to engineer around these issues, it’d make more sense to have a dedicated search page where navigation can continue to work in a standard manner. Using the browser back and forward buttons works normally, and search result pages can be shared since each query will have its own URL with the terms in the parameters.
As I expected, Cloudflare Workers is super fast. On good connnections, I’ve seen search results load as quickly as 60ms, and in my testing I’ve found that even on a (simulated) 2G connection results are loaded within 2 seconds. Plus, the results of each query you make are cached in your browser for a while, which means if you go back to the search page with the same query – maybe you read a post, then hit back to see the other results – the list should re-populate immediately.
And that’s it! A nice project-in-a-day. As the number of posts on the site grows, I’ll need to work out a way to paginate the search results, or at least limit the number returned. I’ve not done that yet though, since I’ll need more posts to test against!