15:28, 3rd of May, 2016

I am researching further how to integrate lunr.js search library into static website’s build process and its front-end.

It looks to me that none of the sources on the Net are truly explaining how lunr.js works (including lunr.js official documentation). Bloggers below might have implemented the searches on their (static) blogs and written articles about integration, but writeups are unsuitable for audiences who are using different static website engines and/or use different build processes for indexes.

Matthew Daly


The problem with Matthew’s write-up is that he uses his own static website generator, and lunr.js indexing is coupled to his article build process. He has the array of blog post objects (it is unclear where does that array come from) which acts like a store for lunr.js. I cannot get that store in the first place!

I am grateful that Matthew took the time to write up the process but I need a different solution.

Katy Decorah


Katy uses Jekyll, but her code is a monolithic chunk where Jekyll and jQuery are coupled together to build the index first, to listen to the user input and to perform searches. I do not like this coupling, and I prefer to build the index separately using my CMS into a JSON file and then use jQuery to reference it.

I am also grateful that Katy took the time to write up the article and even open-source all the code, but I am not using Jekyll, and her solution is coupled with Jekyll too tightly.

Jonas Wagner


The article has the most elegant code of all three, but it is same thing — it is not clear where does the articles’ array (store) comes from, and, also, JSON-baking is coupled with index-making.

Jonas’ code is super-elegant there’s lots to learn from it. However, it is not the thing I am seeking.

The Plan

My plan is to get Hugo to generate JSON-like HTML page during the build, which I minify and rename into the real JSON file.

Then, on each page, there will be a search-specific JS file which loads that JSON and performs the searches on it and shows the results.

  1. CMS produces combined index and store .JSON file of all website’s contents upon the (Hugo or any other CMS) build.
  2. In production, jQuery loads .JSON file into Lunr.js and queries the index and shows the results querying result Integer coming from index against an array of the store.

There will be no mixing between CMS operations (iteration of articles) and JS (neither jQuery nor Lunr).

Oh, by the way, hugo-lunr library sucks. It generates the lunr.json index with only “uri”, “content” and “tags”. It is enough to build index, but not enough to build store which is queried using search result number. In other words, lunr will spit out only ID’s of the content, and if I use this json from hugo-lunr, it will not be enough to show results properly. The store is the full array that is queried with the search result (which is integer number).

While hugo-lunr uses 3 fields: uri+content+tags, I will generate a full set of 7: url+title+subtitle+section+tags+description+content (including full URL with “http” part, which does change from “http” in development builds to “https” in production builds). I cannot use hugo-lunr because of missing http(s) part — I need the full URL because I am not going to bloat my build process.


I want to separate the Lunr.js index/store build from the search querying/result showing part. Let’s see how it goes.