DEV Community

Cover image for Simple Static site/blog search in 14 Lines of JavaScript
Christian
Christian

Posted on • Originally published at cri.dev

Simple Static site/blog search in 14 Lines of JavaScript

Originally posted on cri.dev

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>
Enter fullscreen mode Exit fullscreen mode

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-items data-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'
      })
    })
  }
})()
Enter fullscreen mode Exit fullscreen mode

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>
Enter fullscreen mode Exit fullscreen mode

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.

Originally posted on cri.dev

Discussion (0)