multilingual related posts in jekyll using data and language detection

Why Multilingual Related Posts Matter

For multilingual Jekyll sites, simply reusing the same related post data across all languages leads to a poor UX. Users might click related links that aren’t in their preferred language. This breaks immersion, especially in knowledge bases or documentation.

✅ Goal:

  • Only show related posts that match the current post's language
  • Support shared related post groups across languages
  • Optional: Fallback if translation is missing

Step 1: Add Language to Post Front Matter

Add lang to each post:

---
title: "Optimisasi Template di Jekyll"
lang: id
related_group: template-performance
---

And its English version:

---
title: "Template Optimization in Jekyll"
lang: en
related_group: template-performance
---

Step 2: Update YAML Related Group File

Reuse same group keys for all languages, keeping just URLs:

template-performance:
  title:
    en: "Template Optimization Series"
    id: "Seri Optimisasi Template"
  posts:
    - /jekyll/template-basics/
    - /jekyll/layout-optimizations/
    - /jekyll/template-performance/
    - /jekyll/minification/

Step 3: Multilingual Logic in Layout or Include

Use the following Liquid logic to render related posts that match page.lang:

{% assign group_key = page.related_group %}
{% assign group_data = site.data.related[group_key] %}
{% if group_data %}
  {% assign lang = page.lang | default: "en" %}
  <div class="related-posts">
    <h3>{{ group_data.title[lang] | default: group_data.title["en"] }}</h3>
    <ul>
    {% for url in group_data.posts %}
      {% assign post = site.posts | where: "url", url | where: "lang", lang | first %}
      {% if post and post.url != page.url %}
        <li><a href="{{ post.url }}">{{ post.title }}</a></li>
      {% endif %}
    {% endfor %}
    </ul>
  </div>
{% endif %}

This code:

  • Loads the group from _data/related.yml
  • Uses the correct group title based on the page language
  • Only displays related posts that match the current language

Optional: Language Fallback for Missing Translations

If a translation is missing, you can show a fallback post (e.g., English):

{% assign fallback_post = site.posts | where: "url", url | where: "lang", "en" | first %}
{% assign post = site.posts | where: "url", url | where: "lang", lang | first | default: fallback_post %}

Step 4: Add Translated Titles to Related YAML

To make it fully multilingual, include title translations in your YAML:

jekyll-basics:
  title:
    en: "Jekyll Basics Series"
    id: "Seri Dasar Jekyll"
  posts:
    - /jekyll/setup/
    - /jekyll/structure/
    - /jekyll/markdown-guide/

Use {{ group_data.title[page.lang] }} to render it dynamically.

Optional: Language-Based Navigation Menus

You can even use this data structure to build multilingual section menus per language:

<nav class="group-nav">
  <h4>{{ group_data.title[lang] }}</h4>
  <ul>
  {% for url in group_data.posts %}
    {% assign post = site.posts | where: "url", url | where: "lang", lang | first %}
    {% if post %}
      <li{% if post.url == page.url %} class="active"{% endif %}>
        <a href="{{ post.url }}">{{ post.title }}</a>
      </li>
    {% endif %}
  {% endfor %}
  </ul>
</nav>

Recap: Why This System Works

  • 📌 Keeps logic clean — data-driven instead of per-post
  • 🌍 Language-aware related post experience
  • 💡 Can be expanded into navigation, sidebars, or custom blocks

What’s Next?

We’ve now built:

  1. Basic related post system using front matter
  2. Advanced system using _data/related.yml
  3. Multilingual support based on page.lang

In the next part, we'll explore **automatically generating related post suggestions** using Liquid filters, word overlaps, or tag intersections—ideal when you don’t want to curate related groups manually.


Archives / All Content


© BoostScopeNest . All rights reserved.