Part III - Multilingual
Part III: Building the multi-lingual site
Let’s now build our multilingual site using the Polyglot plugin. The site is based on Jekyll’s minima
theme, so if you use another theme, the steps might look different in detail, but should be rather similar.
Step 1: Install the plugin
Navigate to your publishing source directory /docs
and add the following to your Gemfile
:
group :jekyll_plugins do
gem "jekyll-polyglot"
end
Alternatively, install the gem locally following the description in the Polyglot README.
Then specify the plugin in your _config.yml
:
plugins:
- jekyll-polyglot
Run bundle install
to finalize the installation.
Step 2: Configure the plugin
Please refer to the Polyglot README for details on the configuration. For my purposes (English as default language, German as second language), the following configuration in _config.yml
was sufficient:
# Polyglot language plugin settings
languages: ["en", "de"]
default_lang: "en"
exclude_from_localization: ["assets", "javascript", "images", "css", "public"]
parallel_localization: true
Step 3: Localize your metadata
The site will use some metadata like the title, the description and the localized date format, which are stored in the _config.yml
file. You need to add a language specific title, description and date format:
title:
en: Multi-lingual GitHub Page
de: Mehrsprachige GitHub-Seite
description:
en: A sample multi-lingual GitHub Page built with a Jekyll plugin not supported by GitHub Pages.
de: Eine mehrsprachige Demoseite erstellt mit einem von GitHub Pages nicht unterstützten Jekyll-Plugin
date_formats:
en: "%b. %e, %Y" # e.g.: Sep. 1, 2022
de: "%d.%m.%y" # e.g.: 1.9.22
The title is used in the header.html
file of the minima
theme. Therefore we need to override the remote header.html
file by creating a _includes
folder in the top level publishing folder (here: docs
) and save a copy there. Next, we need to let Jekyll know which language we’re in by adding the following line as first line in header.html
, which creates the variable lang
and assigns the current language:
{% assign lang = site.active_lang %}
<header class="site-header">
...
Finally, we need to modify the line containing {{ site.title | escape }}
with {{ site.title[lang] | escape }}
.
The description is used in the footer.html
file, so simply repeat the steps above, but replace {{ site.description | escape }}
with {{ site.description[lang] | escape }}
.
The date format is used in both the home.html
as well as the post.html
in the Minima _layouts
folder. So, create your own _layouts
folder and copy the two files there. Then add in each file the {% assign lang = site.active_lang %}
line in the beginning, just like above, and finally replace the lines containing {%- assign date_format = site.minima.date_format | default: "%b %-d, %Y" -%}
with {%- assign date_format = site.date_formats[lang] | default: "%b %-d, %Y" -%}
.
Step 4: Localize your title tag
As next step, we have to take care of the <title>
tag in Jekyll’s built-in SEO section, because the site description is also used there. The title tag is used by search engines, but also by most browsers to name the browser tab. As we cannot pass a custom title to Jekyll’s SEO section, we need to disable the display of the title there and create our own <title>
tag instead.
To do so, we need to override Minima’s head.html
(and along with it the custom-head.html
, otherwise we’d run into an error when building the site). So copy those two files from Minima’s _includes
folder to your _includes
folder and open head.html
for editing (you can leave custom-head.html
untouched, but may also use for further customizations like adding a favicon).
Modify the line {%- seo -%}
to {%- seo title=false -%}
.
For some reason, which I didn’t dig in deeper, overriding
head.html
lead to my site no longer finding the right stylesheet. I had to change the line<link rel="stylesheet" href="/multilingual-github-pages/assets/css/style.css">
to<link rel="stylesheet" href="/multilingual-github-pages/assets/main.css">
to fix it.
Finally, we’ll have to add our own custom title in head.html
. As very first line of the file, set the language by adding {% assign lang = site.active_lang %}
.
Then add the following code before the modified {%- seo title=false -%}
line:
<title>
{% if page.title %}{{ page.title }} - {% endif %}
{% if site.title[lang] %}{{ site.title[lang] }}{% endif %}
</title>
It will add the page title, if set in the frontmatter of the file, and then append the localized site title, separated by a slash.
Step 5: Localize your main menu
Minima allows you to define the order of the top menu items by adding those to _config.yml
. We need to do this for all languages:
# Top menu order
header_pages:
en:
- about-en.md
- prerequisites-en.md
- part1-setup-en.md
- part2-maintain-en.md
- part3-multilingual-en.md
de:
- about-de.md
- prerequisites-de.md
- part1-setup-de.md
- part2-maintain-de.md
- part3-multilingual-de.md
Next, in header.html
change {%- assign page_paths = site.header_pages | default: default_paths -%}
to {%- assign page_paths = site.header_pages[lang] | default: default_paths -%}
.
Step 6: Localize your pages
Pages are localized by adding one file per language and using the language code to extend the filename. With en
being the default language and de
the additional language for this example, we will need to have a ...-en.md
and a ...-de.md
version for each file we want to localize (also works with html
files).
In addition, we need to add the identical permalink
and a lang
tag to the frontmatter of each file.
So, rename your index.md
to index-en.md
and add the following lines to the frontmatter:
---
layout: home
permalink: /
lang: en
---
Duplicate the file and save it as index-de.md
. Translate the content and add the following lines to the frontmatter:
---
layout: home
permalink: /
lang: de
---
It is very important to have the permalink identical in all language files.
Repeat the same procedure for all your pages. My about.md
, for example, becomes about-en.md
and has the following frontmatter:
---
layout: page
title: About
permalink: /about/
lang: en
---
My about-de.md
has the following frontmatter:
---
layout: page
title: Über
permalink: /about/
lang: de
---
Step 7: Localize your posts
In the _posts
folder, create a subfolder for each additional language (not the default language!). In my case, I only created a docs/_posts/de
folder. Copy all posts, which you want translated, into that folder. If you leave a post away, the Polyglot plugin will use the default language post instead (see the Welcome to Jekyll
post in my sample site for a demonstration of this feature).
Don’t change the filename of the post in the language subfolder!
Finally, add the lang
tag in the frontmatter of all posts (also those in the default language).
Step 8: Add a language switcher
To enable the user to switch between languages, I added a language switcher in header.html
. Add the following code before the closing </header>
tag:
<div class="wrapper">
{% assign is_first_language = true %}
<!-- jekyll-polyglot will process ferh= into href= through the static_href liquid block tag without relativizing the url; useful for making language navigation switchers -->
{% for tongue in site.languages %}
{% if is_first_language == false %}|{% endif %}
<a {% if tongue == site.active_lang %}style="font-weight: bold;"{% endif %} {% static_href %}href="{% if tongue == site.default_lang %}{{site.baseurl}}{{page.url}}{% else %}{{site.baseurl}}/{{ tongue }}{{page.url}}{% endif %}"{% endstatic_href %} >{{ tongue }}</a>
{% assign is_first_language = false %}
{% endfor %}
</div>
Deploy your site using the deploy.sh
script and you should be good to go with your first multilingual Jekyll site.