This is my approach to a purely client side search feature for static blogs and sites.
I am currently using this under /posts to let readers search through my blog posts.
Read more below about how to integrate it in your site.
Backstory
In 2015 I did a similar thing for Jekyll sites, namely Simple-Jekyll-Search
It’s gotten quite a bit of attention and merged various Pull-Requests (64!) from others.
I ditched Jekyll a few years ago, to use a JavaScript based static site generator:
My home-made static site generator devblog, and settled with Eleventy
How it works
Under /posts I render the full list of blog posts.
(Not with the full content but with an excerpt/description.)
In my Nunjucks template I render the posts like this:
<div class="searchable">
<input type="text" autofocus placeholder="🔍 Search posts"/>
{% set postslist = collections.post | reverse %}
{% for post in postslist %}
<div class="searchable-item" data-search="{{ post.data.title | escape }} {{ post.data.tags | json | escape }}">
...
</div>
{% endfor %}
</div>
The idea is the following:
Within a .searchable
element
- look for a
input
element and attach an event listener to it (keyup
event) - when searching, parse all
.searchable-item
sdata-search
attribute and test a RegExp on it - make items that match visible, and make others disappear
Code
This is the full code for the search functionality on this blog:
;(function search () {
;[...document.querySelectorAll('.searchable')].forEach(makeSearchable)
function makeSearchable ($searchable) {
const $searchableItems = [...$searchable.querySelectorAll('.searchable-item')]
const $search = $searchable.querySelector('input')
$search.addEventListener('keyup', (e) => {
$searchableItems.forEach(function ($el) {
const text = $el.getAttribute('data-search') || $el.innerText
const show = new RegExp(e.target.value, 'i').test(text)
$el.style.display = show ? '' : 'none'
})
})
}
})()
How to integrate it on your site
Grabbed the JavaScript above and put it in a <script>
tag.
Define a minimal markup to enable the search functionality:
<div class="searchable">
<input type="text" autofocus placeholder="🔍 Search posts"/>
<!-- Loop through your blog posts -->
<div class="searchable-item">
...
</div>
</div>
Make sure you have the wrapper element .searchable
, containing an input field and your post items with the .searchable-item
class.
By default the search function will match the blog posts to filter with the element’s innerText
.
Optionally, apply a data-search
attribute to each .searchable-item
and set the value of your blog post title, tags, short description etc.
Full example
Check out a full example on CodePen if you need to better understand how to structure your markup.
Here is how it looks
JavaScript search
some description
Another JavaScript library
some other description
Design resources
description about design resources
Other topic
some other topic description