adding multilingual and version-aware search in jekyll knowledge base
Why You Need Smart Search in Multilingual Documentation
As your Jekyll knowledge base grows and supports multiple languages and versions, users expect a fast way to find the right content without navigating deep menu structures.
While Jekyll doesn’t support server-side search, we can build powerful client-side search using Lunr.js or Elasticlunr.js, enhanced with custom indexing strategies that respect language and version boundaries.
What We’re Building
By the end of this article, you’ll have:
- A language-aware and version-specific index built at build time.
- Search results scoped to the current language and version context.
- Lightweight Lunr.js integration that works natively on GitHub Pages.
Step 1: Define Structured Index Data per Language/Version
We’ll generate a JSON index for each language-version combination using a custom Jekyll collection or generator:
_site/
search/
index-en-v1.json
index-en-v2.json
index-id-v1.json
Inside your Jekyll config:
# _config.yml
defaults:
- scope:
path: ""
values:
layout: default
collections:
docs:
output: true
Step 2: Create a Search Index Page for Each Language/Version
Example: /search/en/v2/ will load index-en-v2.json.
---
layout: search
lang: en
version: v2
title: Search EN v2
---
<div id="searchbox">
<input type="text" id="query" placeholder="Search documentation..." />
<ul id="results"></ul>
</div>
Step 3: JavaScript to Load the Right Index
This script auto-detects the right JSON based on page metadata:
<script src="https://unpkg.com/lunr/lunr.min.js"></script>
<script>
const lang = "{{ page.lang }}";
const version = "{{ page.version }}";
const indexUrl = `/search/index-${lang}-${version}.json`;
fetch(indexUrl)
.then(res => res.json())
.then(docs => {
const idx = lunr(function () {
this.ref("url");
this.field("title");
this.field("body");
docs.forEach(doc => this.add(doc));
});
const input = document.getElementById("query");
const results = document.getElementById("results");
input.addEventListener("input", function () {
const query = this.value;
const matches = idx.search(query);
results.innerHTML = matches.map(match => {
const doc = docs.find(d => d.url === match.ref);
return `<li><a href="${doc.url}">${doc.title}</a></li>`;
}).join("");
});
});
</script>
Step 4: Build the JSON Index with Liquid
In /search/index-en-v2.json layout:
---
layout: none
---
[
{% assign docs = site.docs | where:"lang","en" | where:"version","v2" %}
{% for doc in docs %}
{
"url": "{{ doc.url }}",
"title": {{ doc.title | jsonify }},
"body": {{ doc.content | strip_html | truncatewords: 100 | jsonify }}
}{% if forloop.last == false %},{% endif %}
{% endfor %}
]
This ensures each index is language+version scoped, lightweight, and generated at build time.
Optional: Generate All Indexes Automatically
Create search index pages for all combinations using a loop in a custom plugin or manually define:
# In search/ folder
index-en-v1.md
index-en-v2.md
index-id-v1.md
Improving UX: Highlight Results and Add Fallback
You can enhance search results by highlighting the matched keywords:
<script>
// ...after generating results...
results.innerHTML = matches.map(match => {
const doc = docs.find(d => d.url === match.ref);
const snippet = doc.body.split(" ").slice(0, 20).join(" ") + "...";
return `<li><a href="${doc.url}"><strong>${doc.title}</strong><br/>${snippet}</a></li>`;
}).join("");
</script>
Bonus: Combine Indexes for Global Search (Optional)
If you want to allow search across all versions/languages, you can generate a combined index instead of scoped ones. But be careful—it can confuse users if content from other versions appears in the results.
Conclusion
Implementing multilingual and version-aware search in your Jekyll knowledge base doesn’t require external plugins or server infrastructure. With Lunr.js and simple Liquid logic, you can create fast, reliable, and scoped search experiences tailored for your users—especially helpful when working with static sites on GitHub Pages.
This concludes our advanced Jekyll knowledge base series. You now have the tools to build, structure, scale, translate, version, track, and search your documentation site—all while keeping it beginner-friendly, GitHub-native, and easy to contribute to.