Lunrjs search on Jekyll website not working with TypeError

114 Views Asked by At

Update: Although I still haven't figured this out, I found an alternative that works: Search with Lunr.js | Jekyll Codex

I've been following this CloudCannon Academy tutorial on Jekyll search using lunr.js, but I still haven't get it working after many trials and errors.

When I open Microsoft Edge, my default web browser, I got the following errors in search.js:

search.js:47 
        
       Uncaught TypeError: idx.add is not a function
    at search.js:47:11
    at search.js:57:3

I've been following the tutorial step-by-step, so I basically copied everything from the linked webpage above. What I don't understand is that I certainly have defined idx as the tutorial does. And by checking source code, I have successfully retrieved all the post data and stored them in JSON. What did I do wrong?

For your information, I've attached my code below:

(function() {
  function displaySearchResults(results, store) {
    var searchResults = document.getElementById('search-results');

    if (results.length) { // Are there any results?
      var appendString = '';

      for (var i = 0; i < results.length; i++) {  // Iterate over the results
        var item = store[results[i].ref];
        appendString += '<li><a href="' + item.url + '"><h3>' + item.title + '</h3></a>';
        appendString += '<p>' + item.content.substring(0, 150) + '...</p></li>';
      }

      searchResults.innerHTML = appendString;
    } else {
      searchResults.innerHTML = '<li>No results found</li>';
    }
  }

  function getQueryVariable(variable) {
    var query = window.location.search.substring(1);
    var vars = query.split('&');
  
    for (var i = 0; i < vars.length; i++) {
      var pair = vars[i].split('=');
  
      if (pair[0] === variable) {
        return decodeURIComponent(pair[1].replace(/\+/g, '%20'));
      }
    }
  }
  
  var searchTerm = getQueryVariable('query');

  if (searchTerm) {
    document.getElementById('search-box').setAttribute("value", searchTerm);

    // Initalize lunr with the fields it will be searching on. I've given title
    // a boost of 10 to indicate matches on this field are more important.
    var idx = lunr(function () {
      this.field('id');
      this.field('title', { boost: 10 });
      this.field('content');
    });

    for (var key in window.store) { // Add the data to lunr
      idx.add({
        'id': key,
        'title': window.store[key].title,
        'content': window.store[key].content
      });

      var results = idx.search(searchTerm); // Get lunr to perform a search
      displaySearchResults(results, window.store); // We'll write this in the next section
    }
  }
})();
1

There are 1 best solutions below

0
7fc9ecfc6810c58545e1bc3b556003 On

I had the same problem and found help in this Stackoverflow answer.

The issue is that some tutorials are written for Lunr 1.x where that was the correct way to add the index.

In Lunr 2.x the contents need to be added within the same function that defines the fields.

My working code with Lunr 2.3.0 and Jekyll:

var idx = lunr(function() {
  this.ref('id');
  this.field('title', { boost: 10 });
  this.field('content', { boost: 5 });
  this.field('author');
  this.field('categories');

  {% assign count = 0 %}
  {% for post in site.posts %}
    this.add({
      title: {{post.title | jsonify}},
      content: {{post.content | strip_html | jsonify}},
      category: {{post.category | jsonify}},
      tags: {{post.tags | jsonify}},
      id: {{count}}
    });
    {% assign count = count | plus: 1 %}
  {% endfor %}

});