Multilanguage
Create multiple language versions of the same page
Installation
Import this plugin in your _config.ts
file to use it:
import lume from "lume/mod.ts";
import multilanguage from "lume/plugins/multilanguage.ts";
const site = lume();
site.use(multilanguage());
export default site;
See all available options in Deno Doc.
Description
This plugin allows exporting the same page multiple times, once per language. To configure a page as multilanguage, just set in the lang
variable to an array with the available languages. For example:
# This page is in 3 different languages: English, Galician, and Spanish.
lang: [en, gl, es]
title: About me
layout: base-layout.njk
Lume will generate three pages, one per language, prefixing the output path of each page with the language code:
/en/about-me/index.html
/gl/about-me/index.html
/es/about-me/index.html
Define the data
You may want to set different data per language. One way to do this is by adding a suffix to the variable name with a dot plus the language code. For example:
# This page is in 3 different languages: english, galician and spanish.
lang: [en, gl, es]
title: About me
title.gl: Acerca de min
title.es: Acerca de mí
layout: base-layout.njk
In the example above, the title
value has different values for gl
and es
languages. Any unsuffixed value (like layout
) is used by all languages unless there's a suffixed value for that specific language.
You can use suffixed variables inside other objects or arrays. For example:
# This page is in 3 different languages: English, Galician, and Spanish.
lang: [en, gl, es]
title: About me
title.gl: Sobre min
title.es: Acerca de mí
layout: base-layout.njk
links:
- title: My personal site
title.gl: O meu sitio persoal
title.es: Mi sitio personal
url: https://oscarotero.com
- title: Lume
url: https://lume.land
The links
array contains a list of links. Some titles need to be translated to other languages (like the first one), others don't.
Customize the URLs
You can customize the URLs of the multilanguage pages by adding the language suffix to the url
variable:
lang: [en, gl, es]
title: About me
title.gl: Sobre min
title.es: Acerca de mí
layout: base-layout.njk
url.en: /about-me/
url.gl: /sobre-min/
url.es: /acerca-de-mi/
Alternative way to define data
In addition to the suffixes, another way to define different data per language is by creating a root variable with the language code. This can be more useful in some cases. For example:
lang: [en, gl, es]
en:
title: About me
url: /about-me/
gl:
title: Sobre min
url: /sobre-min/
es:
title: Acerca de mí
url: /acerca-de-mi/
layout: base-layout.njk
Links to the translated languages
Automatic rel=alternate links
This plugin not only creates the pages for the different languages, but also automatically inserts the <link rel="alternate" hreflang="{lang}" href="{url}" />
element in the multilanguage pages. For example:
<!doctype html>
<html lang="en">
<head>
<title>About me</title>
<link rel="alternate" hreflang="gl" href="/sobre-min/" />
<link rel="alternate" hreflang="es" href="/acerca-de-mi/" />
</head>
<body>
...
</body>
</html>
Note that the attribute lang
will be inserted automatically in the html
element if it's missing.
Create a language switcher menu
If you want to include the links to the other translations, this plugin also creates the variable alternates
with all alternative pages. This is an example in nunjucks:
<ul class="languages">
{% for pageLang, page in alternates %}
<li>
<a href="{{ page.data.url }}" {% if pageLang == lang %}aria-current="page"{% endif %}>
{{ page.data.title }} ({{ pageLang }})
</a>
</li>
{% endfor %}
</ul>
This code outputs something like:
<ul class="languages">
<li>
<a href="/about-me/" aria-current="page">
About me (en)
</a>
</li>
<li>
<a href="/sobre-min/">
Sobre min (gl)
</a>
</li>
<li>
<a href="/acerca-de-mi/">
Acerca de mí (es)
</a>
</li>
</ul>
Multilanguage paginations
If you want to search and paginate multilanguage pages (for example a blog with posts translated to several languages), this plugin also includes the mergeLanguages
helper to make it easier.
export default function* ({ search, paginate, mergeLanguages }) {
// Search all posts in english, galician and spanish
const enPages = search.pages("lang=en type=post");
const glPages = search.pages("lang=gl type=post");
const esPages = search.pages("lang=es type=post");
// Paginate the results
const en = paginate(enPages, { url: (n) => `/en/posts/${n}/` });
const gl = paginate(glPages, { url: (n) => `/gl/posts/${n}/` });
const es = paginate(esPages, { url: (n) => `/es/posts/${n}/` });
// Merge and yield all paginations
yield* mergeLanguages({en, gl, es});
}