Build a Ready-To-Use Jekyll Setup — Part 2: Bilingual Website

Robin Klöckner
5 min readOct 25, 2022

--

Photo by Brendan Church on Unsplash

Intro

This article is the second part of a series on how to build a Jekyll setup that can be used to develop multi-page websites with static contents in two languages and which are served by an Apache HTTP Server. In the first part of this guide we prepared a basic Jekyll setup with two pages, CSS/Sass and JavaScript.

In This Part

We are going to make our website bilingual without additional plugins. What we want is to have an element in the navigation bar which allows us to toggle the language. Our implementation will meet the following features:

  • When pushing the toggle element, the browser will request the current page in the alternative language
  • The value of the lang attribute in the html element will always adjust to the language code of the current page
  • The path of the URL must match the language of the current page, e.g. the German path of /legal.html must be/impressum.html

Prerequisites

It is recommended that you follow Part 1 of this guide before proceeding. Alternatively you can download the resulting source code from Part 1 on GitHub, as we will use it as a starting point here.

Current State

After completing Part 1 of this guide, the current folder structure looks as follows:

/
_includes/
footer.html
head.html
header.html
nav.html
scripts.html
_layouts/
default.html
_sass/
base.scss
css/
main.scss
js/
main.js
_config.yml
Gemfile
Gemfile.lock
index.html
legal.html

Collections

We start this part by adding the following lines to the existing _config.yml:

The url will be used in the <base> element in the documents head section to serve as the base for all relative paths. The baseurl can be adjusted in case you serve your website from a subdirectory.

In order to make our website bilingual, we need to make use of Jekyll collections. A collection will host the pages belonging to one language. We are taking ISO 639–1 language codes for the collection names. In our case en for English and de for German. We also need to set output true, otherwise the pages of the collections won’t be build.

Next, we delete the index.html and legal.html files and create the folders (collections) _en and _de in the project root directory. They must have the same names as specified in the _config.yml plus a leading underscore.

We now can create the pages corresponding to the respective language, either as HTML or Markdown files.

In the _de/ directory, create the following files with the respective content.

index.html:

The content ist similar to the index.html files from Part 1 of this guide, except that we add two more attributes in the Front Matter, name and lang. lang is used to determine the language of the current file. Its value must equal the name of the collection as defined in the _config.yml configuration file (de), otherwise the method used in this guide won’t work.

name is the cross-language file name, which will be used to determine the current file in the alternative language when when pushing the toggle element. Therefore, the index.html files in both collections need to have home as the value of the name attribute. You can use different names but they have to be the same in German and the English file.

impressum.html:

impressum.html follows the same structure as index.html except the different name.

Next, we need to create the related pages in English. Therefore, create the following files in the _en/ directory.

index.html:

In contrast to the index.html of the German collection, we need to set en as the value of the lang attribute.

legal.html:

legal.html is the English counterpart to impressum.html. Since we want the URL to meet the language of the current page, we choose a different file name for the English version. However, it is important that the values of the name attribute are the same for legal.html and impressum.html, otherwise we won`t be able identify the correct HTML file when toggling the language.

Toggle Element

We now have to implement the toggle element in the navigation bar which requests the current file in a different language. Since the requested URL will be different, depending on the current page, it must be generated dynamically. We therefore need to figure out two things in advance: First, we need to determine the language of the current page, in order to address the collection of the alternative language. Second, we need to determine the name of the current file to select its corresponding counterpart.

Therefore, we modify nav.html as follows:

The first task is accomplished by checking whether the language of the current page is English (line 5). Since we only have one alternative language, I decided for a hard-coded solution. Either in line 6 or 8 we then access the collection for the alternative language by calling the site variable with the desired collection name. The correct file is then determined by comparing the page.name variable of the current file against the names of the files in the selected collection — that is why the value of the name variable needs to be the same in both versions of a file, the German and the English. The correct page is then assigned to the translated variable.

Since where returns an array, we need to loop over translated (line 11 to 13). The url, relative to the root directory, can be retrieved by the page’s url variable, item.url, which is then used to build the reference of the toggle element, depending on the language of the current page. As the label we simply take the value of the page’s lang variable.

Language of the Document

As a last step in this part we need to set the correct language code in the <html> element within the layout file. This is done by linking the value of the lang attribute of the <html> element to the value of the page’s lang variable. Therefore, we modify line 2 of the layout default.html as follows:

Result

We now have the following folder structure:

/
_de/
impressum.html
index.html
_en/
index.html
legal.html
_includes/
footer.html
head.html
header.html
nav.html
scripts.html
_layouts/
default.html
_sass/
base.scss
css/
main.scss
js/
main.js
_config.yml
Gemfile
Gemfile.lock

Running bundle exec jekyll serve in your terminal now builds and serves the website under http://127.0.0.1:4000.

Illustration of the result
Illustration: Result of part 2

The toggle element now requests the same page in the alternative language, the URL also adapts to the selected language and the correct language code is set in the html element.

Source Code

GitHub: Jekyll Setup - Part 2

In the Next Part

At this point, the remaining navigation items are not working properly, since they are not yet dynamically generated. In part three of this guide, we therefore implement a dynamic navigation bar.

MOVE TO PART 3

--

--