Multilingual Docs with Jekyll Collections and Smart Navigation

Why Use Jekyll Collections for Documentation

Jekyll collections allow you to group content beyond standard posts and pages. They’re perfect for structured documentation because you can control order, metadata, and navigation more easily. Combining this with multilingual support creates an elegant and scalable system.

Core Benefits

  • Organized content structure (e.g. tutorials, changelogs, API docs)
  • Supports language segmentation
  • Enables dynamic TOC, related items, and search

Step 1: Define the Collection

Edit your _config.yml to define your multilingual documentation collections:

collections:
  docs:
    output: true
    permalink: /:collection/:path/
defaults:
  - scope:
      path: ""
      type: docs
    values:
      layout: doc
      lang: en

Now create folders for each language under _docs:

_docs/
├── en/
│   ├── getting-started.md
│   └── advanced-features.md
├── id/
│   ├── mulai.md
│   └── fitur-lanjutan.md

Each file includes front matter like:

---
title: "Getting Started"
lang: en
tags: [intro, basics]
order: 1
---

Step 2: Create Language-Aware Navigation

To render dynamic navigation, filter collections by language:

{% assign current_lang = page.lang %}
{% assign localized_docs = site.docs | where: "lang", current_lang | sort: "order" %}

<nav class="toc">
  <ul>
    {% for doc in localized_docs %}
    <li><a href="{{ doc.url }}">{{ doc.title }}</a></li>
    {% endfor %}
  </ul>
</nav>

Step 3: Enable Multilingual Related Content

Just like in previous articles, filter by language and shared tags:

{% assign related_docs = site.docs | where: "lang", page.lang %}
{% assign shared_tags = page.tags %}
{% assign suggestions = related_docs | where_exp: "item", "item.url != page.url and item.tags | intersection: shared_tags | size > 0" %}

Limit to 3–5 suggestions:

{% for suggestion in suggestions limit:5 %}
  <li><a href="{{ suggestion.url }}">{{ suggestion.title }}</a></li>
{% endfor %}

Step 4: Integrate Search for Documentation

As before, create a multilingual index for your docs collection:

---
layout: null
permalink: /search-docs-{{ page.lang }}.json
---
[
  {% assign docs = site.docs | where: "lang", page.lang %}
  {% for doc in docs %}
    {
      "title": "{{ doc.title | escape }}",
      "url": "{{ doc.url }}",
      "excerpt": "{{ doc.content | strip_html | truncate: 160 | escape }}",
      "tags": "{{ doc.tags | join: ', ' }}"
    } {% unless forloop.last %},{% endunless %}
  {% endfor %}
]

Load this into Lunr/ElasticLunr just like previous examples, but point to /search-docs-id.json or /search-docs-en.json.

Step 5: Add Section Anchors and Dynamic TOC

You can use JavaScript to generate a table of contents from headings within each doc:

<div id="auto-toc"></div>

<script>
const headings = document.querySelectorAll('h2, h3')
const toc = document.getElementById('auto-toc')

headings.forEach(h => {
  const id = h.id || h.textContent.trim().toLowerCase().replace(/\s+/g, '-')
  h.id = id
  const link = document.createElement('a')
  link.href = '#' + id
  link.textContent = h.textContent
  toc.appendChild(link)
})
</script>

Optional: Language Switcher

If you name your files similarly (e.g. getting-started.md and mulai.md), you can map languages manually using a YAML data file like _data/doc_links.yml:

getting-started:
  en: /docs/getting-started/
  id: /docs/mulai/

Then in layout:

{% assign doc_key = page.url | split: '/' | last %}
{% assign map = site.data.doc_links[doc_key] %}
{% if map %}
  <a href="{{ map.id }}">Bahasa Indonesia</a>
{% endif %}

Real Use Case: Building a Knowledge Base

Let’s say you run a multilingual SaaS product with English and Indonesian docs. This setup allows you to:

  • Link contextually between related topics in the same language
  • Offer dynamic search per language
  • Maintain a clean, SEO-optimized structure
  • Deploy easily on GitHub Pages with zero backend

Next Step: Interactive Elements and Feedback Loops

Next, we’ll explore how to capture user behavior using JavaScript — like tracking clicks on search results and related posts — to improve relevance over time and better understand what users engage with.

Siap lanjut ke bagian pelacakan interaksi pengguna?


Archives / All Content


© BoostScopeNest . All rights reserved.