automated navigation menus from data files

Why Manual Navigation Is a Problem As your documentation grows in scale and complexity, manually updating navigation menus becomes error-prone and time-consuming. Every time you add a new page or rename a section, you must update multiple navigation structures, often across several files or versions. This redundancy is a breeding ground for inconsistency. To solve this, Jekyll allows the use of YAML data files to drive content generation dynamically. This enables you to define navigation structures once and reuse them across multiple versions, templates, or layouts. Setting Up Data-Driven Navigation Step 1: Create a Data File Create a new file called _data/navigation.yml in your Jekyll root. Here's a basic structure: v1: - title: Getting Started url: /v1/getting-started/ - title: API Reference url: /v1/api/ v2: - title: Introduction url: /v2/introduction/ - title: Usage url: /v2/usage/ - title: API Reference url: /v2/api/ This organize...

search integration with lunr in jekyll

Why Add Search to Jekyll Documentation

As your documentation grows, users may struggle to locate specific pages or keywords using only the navigation menu. By adding a search feature, you improve usability, discovery, and user retention. Since GitHub Pages doesn't support server-side scripts, the solution must run entirely on the client. Lunr.js is a compact search engine built in JavaScript designed for static sites like Jekyll.

What is Lunr.js

Lunr is a JavaScript-based full-text search library that allows you to build an index of your content and search through it directly in the browser. It works offline, doesn’t require server processing, and gives lightning-fast results even for hundreds of pages.

Step 1: Create a Search Index

First, create a JSON index of your content. This file will be consumed by Lunr in the browser. The simplest way is to generate it with a custom Jekyll layout or page.

File: search.json

Add this to your Jekyll project root.

{% raw %}
---
layout: null
permalink: /search.json
---
[
  {% assign pages = site.pages | concat: site.posts %}
  {% for page in pages %}
    {% if page.search != false and page.title %}
    {
      "title": {{ page.title | jsonify }},
      "url": {{ page.url | jsonify }},
      "content": {{ page.content | strip_html | strip_newlines | jsonify }}
    }{% unless forloop.last %},{% endunless %}
    {% endif %}
  {% endfor %}
]
{% endraw %}

This builds a single JSON file listing all searchable content on your site. You can customize it to exclude irrelevant pages by checking for page.search != false.

Step 2: Include Lunr.js and Search UI

Now add the Lunr script and a basic UI form to your layout or dedicated search page.

HTML Snippet

<input type="text" id="search-box" placeholder="Search docs..." />
<ul id="search-results"></ul>

<script src="https://unpkg.com/lunr/lunr.js"></script>
<script>
// Load index and set up search
fetch('/search.json')
  .then(response => response.json())
  .then(data => {
    const idx = lunr(function () {
      this.ref('url')
      this.field('title')
      this.field('content')

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

    document.getElementById('search-box').addEventListener('input', function () {
      const query = this.value;
      const results = idx.search(query);
      const resultList = document.getElementById('search-results');
      resultList.innerHTML = '';

      results.forEach(result => {
        const match = data.find(d => d.url === result.ref);
        const li = document.createElement('li');
        li.innerHTML = '<a href="' + match.url + '">' + match.title + '</a>';
        resultList.appendChild(li);
      });
    });
  });
</script>

Step 3: Styling the Search Experience

To make the search results usable, apply a simple style. You can refine this with your site's existing design system.


#search-box {
  padding: 0.5em;
  font-size: 1rem;
  width: 100%;
  max-width: 500px;
  box-sizing: border-box;
}
#search-results {
  margin-top: 1em;
  list-style: none;
  padding: 0;
}
#search-results li {
  margin-bottom: 0.5em;
}
#search-results a {
  text-decoration: none;
  color: #3366cc;
}

Step 4: Limit Index Size with Excerpts

To reduce index size and improve speed, you can limit the amount of text added per page by adding a search_excerpt to front matter or programmatically cutting the content.

{% raw %}
"content": {{ page.excerpt | strip_html | jsonify }}
{% endraw %}

You can also define your own excerpt field with:

{% raw %}
{% assign excerpt = page.content | markdownify | strip_html | truncatewords: 30 %}
{% endraw %}

Case Study: Open Source SDK Documentation

A team maintaining documentation for five SDKs hosted their docs on GitHub Pages. Users struggled to find endpoint references and sample code. After implementing Lunr search, the bounce rate dropped by 20% and support tickets asking “where is X documented” fell dramatically.

Implementation Details

  • Used a Jekyll collection for endpoints, added search metadata
  • Built a search.json with only relevant fields
  • Customized result rendering with snippet previews

Feedback Highlights

  • "I love that I can type ‘auth’ and find exactly what I need!"
  • "No more scrolling through five pages to get to the endpoint"

Security and Performance Considerations

  • Ensure your search index doesn’t expose sensitive content
  • Compress search.json with gzip or Brotli
  • Use search only on pages that need it (set search: false in front matter for others)
  • Split index files if total content exceeds 1MB

Advanced Features

Lunr supports more than just keyword search. You can implement:

  • Fuzzy search (partial match)
  • Weighted fields (e.g. prioritize title over content)
  • Search suggestions and autocomplete
  • Stemming and stop word filtering

Conclusion

Integrating Lunr.js with Jekyll adds powerful search functionality to your static documentation, improving user navigation and satisfaction without requiring backend infrastructure. With just a JSON index, a few lines of JavaScript, and thoughtful styling, you can create a responsive search experience that rivals server-powered solutions.

This completes our seven-part guide to building scalable, multilingual, and user-friendly documentation systems using Jekyll and GitHub Pages. From structuring navigation to enabling search, your static site is now fully equipped to serve developers, users, and contributors efficiently.


Archives / All Content


© MintTagReach🕒😃😃😃 . All rights reserved.