🔤 Multilingual and i18n support tool for Jekyll Blogs
See the codePolyglot is a fast, painless, open-source internationalization plugin for Jekyll blogs. Polyglot is easy to set up and use with any Jekyll project, and it scales to the languages you want to support. With fallback support for missing content, automatic url relativization, and powerful SEO tools, Polyglot allows any multi-language jekyll blog to focus on content without the cruft.
Jekyll doesn't provide native support for multi-language blogs. This plugin was modeled after the jekyll-multiple-languages-plugin, whose implementation I liked, but execution I didn't.
Add jekyll-polyglot to your Gemfile if you are using Bundler:
group :jekyll_plugins do
gem "jekyll-polyglot"
end
Or install the gem manually by doing gem install jekyll-polyglot and specify the plugin using _config.yml:
plugins:
- jekyll-polyglot
In your _config.yml file, add the following preferences
languages: ["en", "sv", "de", "fr"]
default_lang: "en"
exclude_from_localization: ["javascript", "images", "css", "public", "sitemap", "CNAME"]
parallel_localization: true
serial_default_lang: true
url: https://polyglot.untra.io
These configuration preferences indicate
exclude: [ .gitignore ] ; you should exclude files and directories in your repo you dont want in your built site at all, and exclude_from_localization files and directories you want to see in your built site, but not in your sublanguage sites.)false if building on Windows hosts, or if Polyglot collides with other Jekyll plugins. - If parallel_localization collides with other jekyll plugins, this setting makes polyglot build the default language first before processing the other language sites.The optional lang_from_path: true option enables getting the page language from a filepath segment seperated by / or ., e.g de/first-one.md, or _posts/zh_HK/use-second-segment.md , if the lang frontmatter isn't defined.
If you are deploying to Netlify and use a _redirects file, you can enable automatic localization of redirects:
localize_redirects: true
exclude_from_redirect_localization:
- /signin
- /app
See Localizing Netlify _redirects for more details.
When adding new posts and pages, add to the YAML front matter:
lang: sv
or whatever appropriate I18n language code the page should build for. And you're done. Ideally, when designing your site, you should organize files by their relative urls.
You can see how the live Polyglot website configures and supports multiple languages, and examples of community language contributions.
Polyglot works by associating documents with similar permalinks to the lang specified in their frontmatter. Files that correspond to similar routes should have identical permalinks. If you don't provide a permalink for a post, make sure you are consistent with how you place and name corresponding files:
_posts/2010-03-01-salad-recipes-en.md
_posts/2010-03-01-salad-recipes-sv.md
_posts/2010-03-01-salad-recipes-fr.md
Organized names will generate consistent permalinks when the post is rendered, and Polyglot will know to build separate language versions of the website using only the files with the correct lang variable in the front matter.
In short:
New in 1.8.0
Whenever page_id frontmatter properties are used to identify translations, permalink information for the available languages is available in permalink_lang.
This is useful in order to generate language menus and even localization meta information without redirects!
Sample code for meta link generation:
{% for lang in site.languages %}
{% capture lang_href %}{{site.baseurl}}/{% if lang != site.default_lang %}{{ lang }}/{% endif %}{% if page.permalink_lang[lang] != '/' %}{{page.permalink_lang[lang]}}{% endif %}{% endcapture %}
<link rel="alternate" hreflang="{{ lang }}" {% static_href %}href="{{ lang_href }}"{% endstatic_href %} />
{% endfor %}
New in 1.13.0
Polyglot exposes two arrays on every page describing its translation status:
page.available_languages — language codes that have an actual translation of this page.page.missing_languages — languages that don't yet have a translation of this page.missing_languages is intentionally empty for pages that have no per-language translations at all: a single-source page falls back to identical content for every visitor, so there is nothing missing to flag. Only pages that already have at least one translations report the gaps.
Combine with page.rendered_lang to also flag fallback content on the page itself.
New in 1.7.0
Optionally, for those who may want different URLs on different languages, translations may be identified by specifying a page_id in the frontmatter.
If available, Polyglot will use page_id to identify the page, and will default to the permalink otherwise.
As an example, you may have an about page located in /about/ while being in /acerca-de/ in Spanish just by changing the permalink and specifying a page_id that will link the files as translations:
---
title: About
permalink: /about
lang: en
page_id: about
---
This is us!
---
title: Acerca de
permalink: /acerca-de
lang: es
page_id: about
---
Estos somos nosotros!
Additionally, if you are also using the jekyll-redirect-from plugin, pages coordinated this way will automatically have redirects created between pages.
So /es/about will automatically redirect to /es/acerca-de and /acerca-de can redirect to /about. If you use this approach, be sure to also employ a customized redirect.html.
As of version 1.12, Polyglot also properly supports redirect_from frontmatter across sublanguages. When you add redirect paths to pages in non-default languages, Polyglot will correctly scope those redirects to each language's prefix, preventing duplicate redirects and ensuring proper routing.
Lets say you are building your website. You have an /about/ page written in english, german and
swedish. You are also supporting a french website, but you never designed a french version of your /about/ page!
No worries. Polyglot ensures the sitemap of your english site matches your french site, matches your swedish and german sites too. In this case, because you specified a default_lang variable in your _config.yml, all sites missing their languages' counterparts will fallback to your default_lang, so content is preserved across different languages of your site.
Polyglot only generates hreflang tags for languages that have actual translations. This improves SEO correctness by not advertising language alternatives that don't actually exist.
For example, if you have /about.html in English and Spanish but not French:
hreflang="en", hreflang="es", and hreflang="x-default"hreflang="fr" is generated, even though a French fallback page existsThis behavior:
hreflang tagshreflang for the default language and x-defaultTranslation detection works via:
page_id frontmatter are considered translationslang) are considered translations{% I18n_Headers %} tag searches site.collections and site.pagesNo need to meticulously manage anchor tags to link to your correct language. Polyglot modifies how pages get written to the site so your french links keep visitors on your french blog.
---
title: au sujet de notre entreprise
permalink: /about/
lang: fr
---
Nous sommes un restaurant situé à Paris . [Ceci est notre menu.](/menu/)
becomes
<header class="post-header">
<h1 class="post-title">au sujet de notre entreprise</h1>
</header>
<article class="post-content">
<p>Nous sommes un restaurant situé à Paris . <a href="/fr/menu/">Ceci est notre menu.</a></p>
</article>
Notice the link <a href="/fr/menu/">... directs to the french website.
Even if you are falling back to default_lang page, relative links built on the french site will still link to french pages.
If you defined a site url in your _config.yaml, Polyglot will automatically relativize absolute links pointing to your website directory:
---
lang: fr
---
Cliquez [ici]({{site.url}}) pour aller à l'entrée du site.
becomes
<p>Cliquez <a href="https://mywebsite.com/fr/">ici</a> pour aller à l'entrée du site.
For proper canonical URL handling on multilingual sites, we recommend using Polyglot's {% I18n_Headers %} tag for canonical URLs instead of jekyll-seo-tag's default canonical output. This provides intelligent canonical URL generation that:
page_id and permalink matching for translation detectionSetup with jekyll-seo-tag:
If you're using jekyll-seo-tag, you can disable its canonical output and let Polyglot handle it:
{% seo canonical=false %}
{% I18n_Headers %}
The canonical=false option is available in jekyll-seo-tag v2.9.0+
Fallback Canonical Behavior:
To have fallback pages (pages without translations) point their canonical URL to the default language version, add to your _config.yml:
fallback_canonical_to_default_lang: true
With this option enabled:
/es/sobre-nosotros/)/about/ instead of /es/about/)This improves SEO by:
Note: hreflang URLs pointing to the default language or x-default are intentionally NOT relativized, as they should always point to the canonical language-specific URLs.
New in 1.13.0
When using Polyglot with Netlify, redirect rules defined in a Netlify _redirects file will get relativized (e.g., /github becomes /fr/github on French pages). However the Netlify _redirects file only contains the redirect base paths, which causes 404 errors for localized URLs.
Polyglot can automatically generate language-prefixed versions of your redirects. Enable this feature in your _config.yml:
localize_redirects: true
exclude_from_redirect_localization:
- /signin
- /app
With this configuration, a redirect like:
/github https://github.com/org/repo 302
Will automatically generate localized versions for all your configured languages:
/github https://github.com/org/repo 302
/fr/github https://github.com/org/repo 302
/de/github https://github.com/org/repo 302
/sv/github https://github.com/org/repo 302
Paths listed in exclude_from_redirect_localization will not be localized, which is useful for authentication endpoints or app URLs that should only exist at the root level.
New in 1.4.0 If you dont want a href attribute to be relativized (such as for making a language switcher), you can use the block tag:
{% static_href %}href="..."{% endstatic_href %}
<a {% static_href %}href="/about"{% endstatic_href %}>click this static link</a>
that will generate <a href="/about">click this static link</a> which is what you would normally use to create a url unmangled by invisible language relativization.
Combine with a html minifier for a polished and production ready website.
New in 1.4.0
If you want to control which languages a document can be generated for, you can specify lang-exclusive: [ ] frontmatter. If you include this frontmatter in your post, it will only generate for the specified site languages.
For Example, the following frontmatter will only generate in the en and fr site language builds:
---
lang-exclusive: ['en', 'fr']
---
There are cases where you may want to have a list of key: value pairs of translated content. For example, instead of creating a complete separate file for each language containing the layout structure and localized content, you can create a single file with the layout that will be shared among pages, and then create a language-specific file with the localized content that will be used.
To do this, you can create a file like _data/:lang/strings.yml, one for each language, and Polyglot will bring those keys under site.data[:lang].strings. For example, suppose you have the following files:
_data/en/strings.yml
hello: "Hello"
greetings:
morning: "Good morning"
evening: "Good evening"
_data/pt-br/strings.yml
hello: "Olá"
greetings:
morning: "Bom dia"
evening: "Boa noite"
You can use the site.data to access the localized content in your layouts and pages:
<p>{{ site.data[site.active_lang].strings.hello }}, {{ site.data[site.active_lang].strings.greetings.morning }}</p>
For more information on this matter, check out this post.
To localize collections, you first have to properly define the collection in your _config.yml file. For example, if you have a collection of projects, you can define it like this:
collections:
projects:
output: true
permalink: /:collection/:title/
Note that the permalink definition here is important. Then, you can create a file for each language in the _projects directory, and Polyglot will bring those files under site.projects. For more information, check the related discussion #188.
This plugin makes modifications to existing Jekyll classes and modules, namely Jekyll::StaticFile and Jekyll::Site. These changes are as lightweight and slim as possible. The biggest change is in Jekyll::Site.process. Polyglot overwrites this method to instead spawn a separate process for each language you intend to process the site for. Each of those processes calls the original Jekyll::Site.process method with its language in mind, ensuring your website scales to support any number of languages, while building all of your site languages simultaneously.
Jekyll::Site.process is the entry point for the Jekyll build process. Take care whatever other plugins you use do not also attempt to overwrite this method. You may have problems.
New in 1.8.0
Polyglot issues a :polyglot, :post_write hook event once all languages have been built for the site. This hook runs exactly once, after all site languages been processed:
Jekyll::Hooks.register :polyglot, :post_write do |site|
# do something custom and cool here!
end
New in 1.5.0
Polyglot will only start builds after it confirms there is a cpu core ready to accept the build thread. This ensures that jekyll will build large sites efficiently, streamlining build processes instead of overloading machines with process thrash.
👋 I need assistance with modern ruby best practices for test maintenance with rake and rspec. If you got the advice I have the ears.
Tests are run with test.sh. Tests are in the /spec directory, and test failure output detail can be examined in the rspec.json file. Code Coverage details are in the the coverage directory.
This plugin stands out from other I18n Jekyll plugins.
default_lang.{{ site.languages }} to get an array of your I18n strings.{{ site.default_lang }} to get the default_lang I18n string.{{ site.active_lang }} to get the I18n language string the website was built for. Alternative names for active_lang can be configured via config.lang_vars.{{ page.rendered_lang }} to get the language the page content is actually rendered in (useful for detecting fallback pages).{{ page.available_languages }} to get the array of language codes a page has been translated into.{{ page.missing_languages }} to get the array of configured languages a page has not been translated into (empty when the page has no real translations and falls back identically everywhere).{{ I18n_Headers }} to append SEO bonuses to your website.{{ Unrelativized_Link href="/hello" }} to make urls that do not get influenced by url correction regexes.site.data localization for efficient rich text replacement.page.rendered_langThe page.rendered_lang variable indicates the actual language of a page's content. This is different from site.active_lang, which indicates the language version of the site currently being built.
site.active_lang: The language the site is being built for (e.g., es for the Spanish site)page.rendered_lang: The language of the page's actual content (e.g., en if no Spanish translation exists)When page.rendered_lang != site.active_lang, the page is a fallback page - it's being served in the default language because no translation exists.
Example: Showing a "not translated" notice:
{% if page.rendered_lang != site.active_lang %}
<div class="translation-notice">
This page is not yet available in {{ site.active_lang }}.
Showing {{ page.rendered_lang }} version.
</div>
{% endif %}
Example: Conditional content based on translation status:
{% if page.rendered_lang == site.active_lang %}
<!-- This is an actual translation -->
<p>Welcome to our {{ site.active_lang }} content!</p>
{% else %}
<!-- This is fallback content -->
<p>Content available in {{ page.rendered_lang }} only.</p>
{% endif %}
This is useful for:
Jekyll-polyglot has a few spectacular Search Engine Optimization techniques to ensure your Jekyll blog gets the most out of its multilingual audience. Check them out!
See the example sitemap.xml and robots.txt for how to automatically generate a multi-language sitemap for your page and turn it in for the SEO i18n credit.
The official Sitemap protocol documentation states:
"The location of a Sitemap file determines the set of URLs that can be included in that Sitemap. A Sitemap file located at http://example.com/catalog/sitemap.xml can include any URLs starting with http://example.com/catalog/ but can not include URLs starting with http://example.com/images/."
"It is strongly recommended that you place your Sitemap at the root directory of your web server."
To comply with this, 'sitemap.xml' should be added to the 'exclude_from_localization' list to ensure that only one sitemap.xml file exists in the root directory, rather than creating separate ones for each language.
Currently supports Jekyll 3.0 , and Jekyll 4.0
parallel_localization: false in the _config.ymlconfig.yml will disable sourcemap generation:sass:
sourcemap: never
Please! I need all the support I can get! 🙏
But for real I would appreciate any code contributions and support. This started as an open-source side-project and has gotten bigger than I'd ever imagine! If you have something you'd like to contribute to jekyll-polyglot, please open a PR!
These are talented and considerate software developers across the world that have lent their support to this project. Thank You! ¡Gracias! Merci! Danke! 감사합니다! תודה רבה! Спасибо! Dankjewel! 谢谢!Obrigado!
Feel free to open a PR and list your multilingual blog here you may want to share:
pt-BRarjarunlkohezh-CNittkukhizh-TWpt-PTCopyright (c) Samuel Volin 2025. License: MIT
488 followers · starred Aug 2026
544 followers · starred Jan 2025
56 followers · starred Nov 2020
944 followers · starred Feb 2025
🔤 Multilingual and i18n support tool for Jekyll Blogs
See the codePolyglot is a fast, painless, open-source internationalization plugin for Jekyll blogs. Polyglot is easy to set up and use with any Jekyll project, and it scales to the languages you want to support. With fallback support for missing content, automatic url relativization, and powerful SEO tools, Polyglot allows any multi-language jekyll blog to focus on content without the cruft.
Jekyll doesn't provide native support for multi-language blogs. This plugin was modeled after the jekyll-multiple-languages-plugin, whose implementation I liked, but execution I didn't.
Add jekyll-polyglot to your Gemfile if you are using Bundler:
group :jekyll_plugins do
gem "jekyll-polyglot"
end
Or install the gem manually by doing gem install jekyll-polyglot and specify the plugin using _config.yml:
plugins:
- jekyll-polyglot
In your _config.yml file, add the following preferences
languages: ["en", "sv", "de", "fr"]
default_lang: "en"
exclude_from_localization: ["javascript", "images", "css", "public", "sitemap", "CNAME"]
parallel_localization: true
serial_default_lang: true
url: https://polyglot.untra.io
These configuration preferences indicate
exclude: [ .gitignore ] ; you should exclude files and directories in your repo you dont want in your built site at all, and exclude_from_localization files and directories you want to see in your built site, but not in your sublanguage sites.)false if building on Windows hosts, or if Polyglot collides with other Jekyll plugins. - If parallel_localization collides with other jekyll plugins, this setting makes polyglot build the default language first before processing the other language sites.The optional lang_from_path: true option enables getting the page language from a filepath segment seperated by / or ., e.g de/first-one.md, or _posts/zh_HK/use-second-segment.md , if the lang frontmatter isn't defined.
If you are deploying to Netlify and use a _redirects file, you can enable automatic localization of redirects:
localize_redirects: true
exclude_from_redirect_localization:
- /signin
- /app
See Localizing Netlify _redirects for more details.
When adding new posts and pages, add to the YAML front matter:
lang: sv
or whatever appropriate I18n language code the page should build for. And you're done. Ideally, when designing your site, you should organize files by their relative urls.
You can see how the live Polyglot website configures and supports multiple languages, and examples of community language contributions.
Polyglot works by associating documents with similar permalinks to the lang specified in their frontmatter. Files that correspond to similar routes should have identical permalinks. If you don't provide a permalink for a post, make sure you are consistent with how you place and name corresponding files:
_posts/2010-03-01-salad-recipes-en.md
_posts/2010-03-01-salad-recipes-sv.md
_posts/2010-03-01-salad-recipes-fr.md
Organized names will generate consistent permalinks when the post is rendered, and Polyglot will know to build separate language versions of the website using only the files with the correct lang variable in the front matter.
In short:
New in 1.8.0
Whenever page_id frontmatter properties are used to identify translations, permalink information for the available languages is available in permalink_lang.
This is useful in order to generate language menus and even localization meta information without redirects!
Sample code for meta link generation:
{% for lang in site.languages %}
{% capture lang_href %}{{site.baseurl}}/{% if lang != site.default_lang %}{{ lang }}/{% endif %}{% if page.permalink_lang[lang] != '/' %}{{page.permalink_lang[lang]}}{% endif %}{% endcapture %}
<link rel="alternate" hreflang="{{ lang }}" {% static_href %}href="{{ lang_href }}"{% endstatic_href %} />
{% endfor %}
New in 1.13.0
Polyglot exposes two arrays on every page describing its translation status:
page.available_languages — language codes that have an actual translation of this page.page.missing_languages — languages that don't yet have a translation of this page.missing_languages is intentionally empty for pages that have no per-language translations at all: a single-source page falls back to identical content for every visitor, so there is nothing missing to flag. Only pages that already have at least one translations report the gaps.
Combine with page.rendered_lang to also flag fallback content on the page itself.
New in 1.7.0
Optionally, for those who may want different URLs on different languages, translations may be identified by specifying a page_id in the frontmatter.
If available, Polyglot will use page_id to identify the page, and will default to the permalink otherwise.
As an example, you may have an about page located in /about/ while being in /acerca-de/ in Spanish just by changing the permalink and specifying a page_id that will link the files as translations:
---
title: About
permalink: /about
lang: en
page_id: about
---
This is us!
---
title: Acerca de
permalink: /acerca-de
lang: es
page_id: about
---
Estos somos nosotros!
Additionally, if you are also using the jekyll-redirect-from plugin, pages coordinated this way will automatically have redirects created between pages.
So /es/about will automatically redirect to /es/acerca-de and /acerca-de can redirect to /about. If you use this approach, be sure to also employ a customized redirect.html.
As of version 1.12, Polyglot also properly supports redirect_from frontmatter across sublanguages. When you add redirect paths to pages in non-default languages, Polyglot will correctly scope those redirects to each language's prefix, preventing duplicate redirects and ensuring proper routing.
Lets say you are building your website. You have an /about/ page written in english, german and
swedish. You are also supporting a french website, but you never designed a french version of your /about/ page!
No worries. Polyglot ensures the sitemap of your english site matches your french site, matches your swedish and german sites too. In this case, because you specified a default_lang variable in your _config.yml, all sites missing their languages' counterparts will fallback to your default_lang, so content is preserved across different languages of your site.
Polyglot only generates hreflang tags for languages that have actual translations. This improves SEO correctness by not advertising language alternatives that don't actually exist.
For example, if you have /about.html in English and Spanish but not French:
hreflang="en", hreflang="es", and hreflang="x-default"hreflang="fr" is generated, even though a French fallback page existsThis behavior:
hreflang tagshreflang for the default language and x-defaultTranslation detection works via:
page_id frontmatter are considered translationslang) are considered translations{% I18n_Headers %} tag searches site.collections and site.pagesNo need to meticulously manage anchor tags to link to your correct language. Polyglot modifies how pages get written to the site so your french links keep visitors on your french blog.
---
title: au sujet de notre entreprise
permalink: /about/
lang: fr
---
Nous sommes un restaurant situé à Paris . [Ceci est notre menu.](/menu/)
becomes
<header class="post-header">
<h1 class="post-title">au sujet de notre entreprise</h1>
</header>
<article class="post-content">
<p>Nous sommes un restaurant situé à Paris . <a href="/fr/menu/">Ceci est notre menu.</a></p>
</article>
Notice the link <a href="/fr/menu/">... directs to the french website.
Even if you are falling back to default_lang page, relative links built on the french site will still link to french pages.
If you defined a site url in your _config.yaml, Polyglot will automatically relativize absolute links pointing to your website directory:
---
lang: fr
---
Cliquez [ici]({{site.url}}) pour aller à l'entrée du site.
becomes
<p>Cliquez <a href="https://mywebsite.com/fr/">ici</a> pour aller à l'entrée du site.
For proper canonical URL handling on multilingual sites, we recommend using Polyglot's {% I18n_Headers %} tag for canonical URLs instead of jekyll-seo-tag's default canonical output. This provides intelligent canonical URL generation that:
page_id and permalink matching for translation detectionSetup with jekyll-seo-tag:
If you're using jekyll-seo-tag, you can disable its canonical output and let Polyglot handle it:
{% seo canonical=false %}
{% I18n_Headers %}
The canonical=false option is available in jekyll-seo-tag v2.9.0+
Fallback Canonical Behavior:
To have fallback pages (pages without translations) point their canonical URL to the default language version, add to your _config.yml:
fallback_canonical_to_default_lang: true
With this option enabled:
/es/sobre-nosotros/)/about/ instead of /es/about/)This improves SEO by:
Note: hreflang URLs pointing to the default language or x-default are intentionally NOT relativized, as they should always point to the canonical language-specific URLs.
New in 1.13.0
When using Polyglot with Netlify, redirect rules defined in a Netlify _redirects file will get relativized (e.g., /github becomes /fr/github on French pages). However the Netlify _redirects file only contains the redirect base paths, which causes 404 errors for localized URLs.
Polyglot can automatically generate language-prefixed versions of your redirects. Enable this feature in your _config.yml:
localize_redirects: true
exclude_from_redirect_localization:
- /signin
- /app
With this configuration, a redirect like:
/github https://github.com/org/repo 302
Will automatically generate localized versions for all your configured languages:
/github https://github.com/org/repo 302
/fr/github https://github.com/org/repo 302
/de/github https://github.com/org/repo 302
/sv/github https://github.com/org/repo 302
Paths listed in exclude_from_redirect_localization will not be localized, which is useful for authentication endpoints or app URLs that should only exist at the root level.
New in 1.4.0 If you dont want a href attribute to be relativized (such as for making a language switcher), you can use the block tag:
{% static_href %}href="..."{% endstatic_href %}
<a {% static_href %}href="/about"{% endstatic_href %}>click this static link</a>
that will generate <a href="/about">click this static link</a> which is what you would normally use to create a url unmangled by invisible language relativization.
Combine with a html minifier for a polished and production ready website.
New in 1.4.0
If you want to control which languages a document can be generated for, you can specify lang-exclusive: [ ] frontmatter. If you include this frontmatter in your post, it will only generate for the specified site languages.
For Example, the following frontmatter will only generate in the en and fr site language builds:
---
lang-exclusive: ['en', 'fr']
---
There are cases where you may want to have a list of key: value pairs of translated content. For example, instead of creating a complete separate file for each language containing the layout structure and localized content, you can create a single file with the layout that will be shared among pages, and then create a language-specific file with the localized content that will be used.
To do this, you can create a file like _data/:lang/strings.yml, one for each language, and Polyglot will bring those keys under site.data[:lang].strings. For example, suppose you have the following files:
_data/en/strings.yml
hello: "Hello"
greetings:
morning: "Good morning"
evening: "Good evening"
_data/pt-br/strings.yml
hello: "Olá"
greetings:
morning: "Bom dia"
evening: "Boa noite"
You can use the site.data to access the localized content in your layouts and pages:
<p>{{ site.data[site.active_lang].strings.hello }}, {{ site.data[site.active_lang].strings.greetings.morning }}</p>
For more information on this matter, check out this post.
To localize collections, you first have to properly define the collection in your _config.yml file. For example, if you have a collection of projects, you can define it like this:
collections:
projects:
output: true
permalink: /:collection/:title/
Note that the permalink definition here is important. Then, you can create a file for each language in the _projects directory, and Polyglot will bring those files under site.projects. For more information, check the related discussion #188.
This plugin makes modifications to existing Jekyll classes and modules, namely Jekyll::StaticFile and Jekyll::Site. These changes are as lightweight and slim as possible. The biggest change is in Jekyll::Site.process. Polyglot overwrites this method to instead spawn a separate process for each language you intend to process the site for. Each of those processes calls the original Jekyll::Site.process method with its language in mind, ensuring your website scales to support any number of languages, while building all of your site languages simultaneously.
Jekyll::Site.process is the entry point for the Jekyll build process. Take care whatever other plugins you use do not also attempt to overwrite this method. You may have problems.
New in 1.8.0
Polyglot issues a :polyglot, :post_write hook event once all languages have been built for the site. This hook runs exactly once, after all site languages been processed:
Jekyll::Hooks.register :polyglot, :post_write do |site|
# do something custom and cool here!
end
New in 1.5.0
Polyglot will only start builds after it confirms there is a cpu core ready to accept the build thread. This ensures that jekyll will build large sites efficiently, streamlining build processes instead of overloading machines with process thrash.
👋 I need assistance with modern ruby best practices for test maintenance with rake and rspec. If you got the advice I have the ears.
Tests are run with test.sh. Tests are in the /spec directory, and test failure output detail can be examined in the rspec.json file. Code Coverage details are in the the coverage directory.
This plugin stands out from other I18n Jekyll plugins.
default_lang.{{ site.languages }} to get an array of your I18n strings.{{ site.default_lang }} to get the default_lang I18n string.{{ site.active_lang }} to get the I18n language string the website was built for. Alternative names for active_lang can be configured via config.lang_vars.{{ page.rendered_lang }} to get the language the page content is actually rendered in (useful for detecting fallback pages).{{ page.available_languages }} to get the array of language codes a page has been translated into.{{ page.missing_languages }} to get the array of configured languages a page has not been translated into (empty when the page has no real translations and falls back identically everywhere).{{ I18n_Headers }} to append SEO bonuses to your website.{{ Unrelativized_Link href="/hello" }} to make urls that do not get influenced by url correction regexes.site.data localization for efficient rich text replacement.page.rendered_langThe page.rendered_lang variable indicates the actual language of a page's content. This is different from site.active_lang, which indicates the language version of the site currently being built.
site.active_lang: The language the site is being built for (e.g., es for the Spanish site)page.rendered_lang: The language of the page's actual content (e.g., en if no Spanish translation exists)When page.rendered_lang != site.active_lang, the page is a fallback page - it's being served in the default language because no translation exists.
Example: Showing a "not translated" notice:
{% if page.rendered_lang != site.active_lang %}
<div class="translation-notice">
This page is not yet available in {{ site.active_lang }}.
Showing {{ page.rendered_lang }} version.
</div>
{% endif %}
Example: Conditional content based on translation status:
{% if page.rendered_lang == site.active_lang %}
<!-- This is an actual translation -->
<p>Welcome to our {{ site.active_lang }} content!</p>
{% else %}
<!-- This is fallback content -->
<p>Content available in {{ page.rendered_lang }} only.</p>
{% endif %}
This is useful for:
Jekyll-polyglot has a few spectacular Search Engine Optimization techniques to ensure your Jekyll blog gets the most out of its multilingual audience. Check them out!
See the example sitemap.xml and robots.txt for how to automatically generate a multi-language sitemap for your page and turn it in for the SEO i18n credit.
The official Sitemap protocol documentation states:
"The location of a Sitemap file determines the set of URLs that can be included in that Sitemap. A Sitemap file located at http://example.com/catalog/sitemap.xml can include any URLs starting with http://example.com/catalog/ but can not include URLs starting with http://example.com/images/."
"It is strongly recommended that you place your Sitemap at the root directory of your web server."
To comply with this, 'sitemap.xml' should be added to the 'exclude_from_localization' list to ensure that only one sitemap.xml file exists in the root directory, rather than creating separate ones for each language.
Currently supports Jekyll 3.0 , and Jekyll 4.0
parallel_localization: false in the _config.ymlconfig.yml will disable sourcemap generation:sass:
sourcemap: never
Please! I need all the support I can get! 🙏
But for real I would appreciate any code contributions and support. This started as an open-source side-project and has gotten bigger than I'd ever imagine! If you have something you'd like to contribute to jekyll-polyglot, please open a PR!
These are talented and considerate software developers across the world that have lent their support to this project. Thank You! ¡Gracias! Merci! Danke! 감사합니다! תודה רבה! Спасибо! Dankjewel! 谢谢!Obrigado!
Feel free to open a PR and list your multilingual blog here you may want to share:
pt-BRarjarunlkohezh-CNittkukhizh-TWpt-PTCopyright (c) Samuel Volin 2025. License: MIT
488 followers · starred Aug 2026
544 followers · starred Jan 2025
56 followers · starred Nov 2020
944 followers · starred Feb 2025