Build a Manual with MkDocs #5: Multilingual Docs and Versioning

1 min read

In #4 we put the docs on the internet. As the user base grows, two demands tend to follow: reading the docs in another language, and keeping past docs around for people still using older product versions. This post covers both.

This series, Build a Manual with MkDocs, runs in six parts.

  • #1: From Install to Your First Doc
  • #2: nav and Search — Shaping the Information Structure of Your Docs
  • #3: Writing Content — Code Blocks, Mermaid, and Admonitions
  • #4: Deploy on Cloudflare Pages and Connect a Domain
  • #5: Multilingual Docs and Versioning ← this post
  • #6: Maintenance — Search, Accessibility, and Documentation Culture

In this post we’ll cover adding a language, connecting translation files, and maintaining per-version docs side by side.

Adding a Language — static-i18n #

Multilingual support is added with the mkdocs-static-i18n plugin. First, install it.

Install the i18n plugin
pip install mkdocs-static-i18n

Declare the languages in mkdocs.yml. We’ll use the approach of appending a language code after the filename (suffix).

mkdocs.yml — multilingual
plugins:
  - i18n:
      docs_structure: suffix
      languages:
        - locale: ko
          default: true
          name: 한국어
        - locale: en
          name: English

Placing Translation Files #

You place the per-language versions of the same doc side by side, each with a language code appended to the filename.

Placing translation files
docs/
├─ index.md       # Default language (Korean)
└─ index.en.md    # English

The plugin recognizes the two as translations of the same post and automatically shows a language switcher at the top. Untranslated posts automatically fall back to the default language, so the site doesn’t break even if you don’t translate everything at once.

Versioning — mike #

This is where the strength of MkDocs shows. In the Hugo edition there was no versioning feature, so you had to split things up by folder yourself, but MkDocs has a dedicated tool called mike. It pins a snapshot of the docs for each version and even attaches a version-selector dropdown at the top.

Deploying a version with mike
pip install mike

# Deploy version 1.0 and attach the 'latest' alias
mike deploy --push --update-aliases 1.0 latest

# Specify which version opens by default
mike set-default --push latest

Then, set the version provider to mike in mkdocs.yml, and a version selector appears in the header.

mkdocs.yml — version selector
extra:
  version:
    provider: mike

When the product moves up to 2.0, you just pin a new snapshot with mike deploy 2.0 latest. The 1.0 docs stay as they are, so users on the older version can keep referring to them.

Wrapping Up #

In this post we added a language with static-i18n and connected translations, and attached version snapshots and a selector with mike. The strength of the MkDocs ecosystem is that both multilingual support and versioning are solved cleanly with plugins.

The next post is the last. We’ll close out the series by covering the operations perspective: search, accessibility, and the maintenance habits that keep docs alive for a long time.

X