version-aware search indexing in jekyll docs

Why Version-Specific Search Matters

When your documentation supports multiple versions, having a single unified search index often leads to confusion. Users reading version 1.0 may see outdated or broken results from version 2.0, and vice versa.

To improve accuracy, you can create separate search indexes for each version and load the appropriate one dynamically. This guide walks you through building version-specific client-side search with Jekyll and Lunr.js, tailored for beginners.

Project Structure Assumptions

This tutorial assumes your Jekyll documentation is structured like this:

/docs/
  ├── v1.0/
  ├── v2.0/
  ├── v3.0/
  └── index.html

Each folder contains version-specific documentation pages.

Step 1: Generate a Search Index per Version

Create a page in each version folder called search.json to store the content for that version’s search. Example for v2.0:

{% raw %}
---
layout: null
permalink: /docs/v2.0/search.json
---
[
  {% assign pages = site.pages | where_exp: "item", "item.url contains '/docs/v2.0/'" %}
  {% for page in pages %}
    {
      "title": {{ page.title | jsonify }},
      "url": {{ page.url | relative_url | jsonify }},
      "content": {{ page.content | strip_html | normalize_whitespace | jsonify }}
    }{% if forloop.last == false %},{% endif %}
  {% endfor %}
]
{% endraw %}

Repeat this for each version folder by changing the path in the filter and permalink.

Step 2: Load the Correct Index with JavaScript

Now that each version has its own search.json, update your search script to load the correct one based on the current URL.

Basic JavaScript Example

<script>
function getVersionFromPath(path) {
  const match = path.match(/\/docs\/(v\d+\.\d+)\//);
  return match ? match[1] : null;
}

const currentVersion = getVersionFromPath(window.location.pathname) || 'v3.0';
const indexPath = `/docs/${currentVersion}/search.json`;

fetch(indexPath)
  .then(response => response.json())
  .then(pages => {
    const idx = lunr(function () {
      this.field('title');
      this.field('content');
      this.ref('url');

      pages.forEach(doc => this.add(doc));
    });

    document.getElementById('searchInput').addEventListener('input', function () {
      const query = this.value;
      const results = idx.search(query);
      displayResults(results, pages);
    });
  });

function displayResults(results, pages) {
  const container = document.getElementById('results');
  container.innerHTML = '';

  results.forEach(result => {
    const match = pages.find(p => p.url === result.ref);
    const div = document.createElement('div');
    div.innerHTML = `<a href="${match.url}">${match.title}</a>`;
    container.appendChild(div);
  });
}
</script>

Step 3: Improve Performance by Indexing Only Docs

Be sure your search index only includes documentation content (not homepage, changelogs, etc.). Use URL filters to isolate docs per version folder.

Step 4: Display Version in the Search UI

To make it clear to users which version they are searching, you can display the current version near the search input:

<p>Searching in version: <strong id="versionLabel"></strong></p>
<script>
document.getElementById('versionLabel').textContent = currentVersion;
</script>

Handling Edge Cases

  • If users are on /docs/ with no version, default to your latest version.
  • If search.json is missing for a version, fallback to a message like "Search not available for this version."
  • Keep your search index lightweight by limiting it to titles, summaries, and important paragraphs only.

Keep Your Indexes in Sync

Remember to regenerate each version's search.json whenever you update the documentation. If you're using GitHub Actions or CI/CD, include a step to rebuild search indexes as part of your deployment process.

Conclusion

Version-specific search indexes dramatically improve the experience of reading and navigating your documentation. They ensure users are never shown results from the wrong version, which is especially important for software with breaking changes or new features over time.

In the next article, we'll focus on enhancing the user interface of your Jekyll-based knowledge base — including better navigation, keyboard shortcuts, and contextual search highlighting.