Adding Search to a Static Website
My website is made up of static pages, there is no central database. How do I implement search functionality so users can find the content they're looking for?
One of the biggest downsides when building static websites is the inability to query your data. Sure you can tag and categorise pages and create yet another page that lists them, but that alone is extremely limiting for the user. If you want to give users the ability to search through your website using plain text or any combination of tags, you can't do so on a static website. Well, you can, by creating endless permutations of every possible user input but let's not get into that.
So, what's the solution? There's a few. None of them are perfect.
Option 1. Use a third-party service as your search engine
Google and others already provide site-specific search widgets for you to drop in and use. The downside is, you'll need to wait for their bots to crawl your pages for any changes. Also, functionality is restricted and you'll have a "Google" themed widget messing up your UI.
Option 2. Run searches on the server-side
This one's pretty intuitive. Since your page requires user input, it makes sense to just create a backend that can process those inputs and provide a result. The downside is, you lose some benefits of static generation, namely the reduced complexity in your infrastructure.
Option 3. Run searches on the client-side
Running searches on the client-side
So, we're going with Option 3. To get this working, we'll need 3 things:
- What you're searching. e.g. your blog posts.
- What the user's searching for. e.g. the search string.
- How you're searching for it. i.e. the search algorithm.
1. Getting what you're searching.
What do you want users to search? It's worth mentioning that the more you want your users to be able to search, the more data they'll have to download and process. Here's what I went with.
- Post titles
- Post tags
Next, is what you want to present in the search results. I wanted to show a preview of the post, which required
- Post title
- Post image
- Post date
- Post url
So now we have a complete set of attributes:
- Post title, string, searchable
- Post tags, array of strings, searchable
- Post image, url string
- Post date, ISO Date string
- Post url, url string
Now we need to generate the data to be consumed client-side. This is simple to do with most static site generators, just create a template that outputs to JSON. Here's an example in Middleman using ERB.
This produces something like:
2. Getting what the user's searching for
This will just be a simple form. When the form is submitted, it'll come back to the same page and add the search string as the query parameter
q. We'll also add an empty
searchResults element to populate later.
<!-- https://your-website.com/search -->
3. Run the search
I went with Fuse.js to run a fuzzy search over the posts. It's lightweight and fast with plenty of flexibility. You'll probably want to tweak some options yourself to get the best results from it.
To keep things familiar, I'm using JQuery. You can use any framework your want for this and make it really complex with real-time search and the like. The main point here is to outline the approach.
// Extract the `q` query parameter
Include both Fuse.js and this script on your search page and you're good to go.
That's all there is to it! You can see this approach in action on my search page. It's not perfect but for a simple blog, it's good enough.