--- title: Multilingual Mode linktitle: Multilingual and i18n description: Hugo supports the creation of websites with multiple languages side by side. date: 2017-01-10 publishdate: 2017-01-10 lastmod: 2017-01-10 categories: [content management] keywords: [multilingual,i18n, internationalization] menu: docs: parent: "content-management" weight: 150 weight: 150 #rem draft: false aliases: [/content/multilingual/,/tutorials/create-a-multilingual-site/] toc: true --- You should define the available languages in a `languages` section in your site configuration. > Also See [Hugo Multilingual Part 1: Content translation](https://regisphilibert.com/blog/2018/08/hugo-multilingual-part-1-managing-content-translation/) ## Configure Languages The following is an example of a site configuration for a multilingual Hugo project: {{< code-toggle file="config" >}} defaultContentLanguage = "en" copyright = "Everything is mine" [params] [params.navigation] help = "Help" [languages] [languages.en] title = "My blog" weight = 1 [languages.en.params] linkedin = "https://linkedin.com/whoever" [languages.fr] title = "Mon blogue" weight = 2 [languages.fr.params] linkedin = "https://linkedin.com/fr/whoever" [languages.fr.params.navigation] help = "Aide" [languages.ar] title = "مدونتي" weight = 2 languagedirection = "rtl" [languages.pt-pt] title = "O meu blog" weight = 3 {{< /code-toggle >}} Anything not defined in a `languages` block will fall back to the global value for that key (e.g., `copyright` for the English `en` language). This also works for `params`, as demonstrated with `help` above: You will get the value `Aide` in French and `Help` in all the languages without this parameter set. With the configuration above, all content, sitemap, RSS feeds, paginations, and taxonomy pages will be rendered below `/` in English (your default content language) and then below `/fr` in French. When working with front matter `Params` in [single page templates][singles], omit the `params` in the key for the translation. `defaultContentLanguage` sets the project's default language. If not set, the default language will be `en`. If the default language needs to be rendered below its own language code (`/en`) like the others, set `defaultContentLanguageInSubdir: true`. Only the obvious non-global options can be overridden per language. Examples of global options are `baseURL`, `buildDrafts`, etc. **Please note:** use lowercase language codes, even when using regional languages (ie. use pt-pt instead of pt-PT). Currently Hugo language internals lowercase language codes, which can cause conflicts with settings like `defaultContentLanguage` which are not lowercased. Please track the evolution of this issue in [Hugo repository issue tracker](https://github.com/gohugoio/hugo/issues/7344) ### Disable a Language You can disable one or more languages. This can be useful when working on a new translation. ```toml disableLanguages = ["fr", "ja"] ``` Note that you cannot disable the default content language. We kept this as a standalone setting to make it easier to set via [OS environment](/getting-started/configuration/#configure-with-environment-variables): ```bash HUGO_DISABLELANGUAGES="fr ja" hugo ``` If you have already a list of disabled languages in `config.toml`, you can enable them in development like this: ```bash HUGO_DISABLELANGUAGES=" " hugo server ``` ### Configure Multilingual Multihost From **Hugo 0.31** we support multiple languages in a multihost configuration. See [this issue](https://github.com/gohugoio/hugo/issues/4027) for details. This means that you can now configure a `baseURL` per `language`: > If a `baseURL` is set on the `language` level, then all languages must have one and they must all be different. Example: {{< code-toggle file="config" >}} [languages] [languages.fr] baseURL = "https://example.fr" languageName = "Français" weight = 1 title = "En Français" [languages.en] baseURL = "https://example.com" languageName = "English" weight = 2 title = "In English" {{ code-toggle >}} With the above, the two sites will be generated into `public` with their own root: ```bash public ├── en └── fr ``` **All URLs (i.e `.Permalink` etc.) will be generated from that root. So the English home page above will have its `.Permalink` set to `https://example.com/`.** When you run `hugo server` we will start multiple HTTP servers. You will typically see something like this in the console: ```bash Web Server is available at 127.0.0.1:1313 (bind address 127.0.0.1) Web Server is available at 127.0.0.1:1314 (bind address 127.0.0.1) Press Ctrl+C to stop ``` Live reload and `--navigateToChanged` between the servers work as expected. ### Taxonomies and Blackfriday Taxonomies and [Blackfriday configuration][config] can also be set per language: {{< code-toggle file="config" >}} [Taxonomies] tag = "tags" [blackfriday] angledQuotes = true hrefTargetBlank = true [languages] [languages.en] weight = 1 title = "English" [languages.en.blackfriday] angledQuotes = false [languages.fr] weight = 2 title = "Français" [languages.fr.Taxonomies] plaque = "plaques" {{ code-toggle >}} ## Translate Your Content There are two ways to manage your content translations. Both ensure each page is assigned a language and is linked to its counterpart translations. ### Translation by filename Considering the following example: 1. `/content/about.en.md` 2. `/content/about.fr.md` The first file is assigned the English language and is linked to the second. The second file is assigned the French language and is linked to the first. Their language is __assigned__ according to the language code added as a __suffix to the filename__. By having the same **path and base filename**, the content pieces are __linked__ together as translated pages. {{< note >}} If a file has no language code, it will be assigned the default language. {{ note >}} ### Translation by content directory This system uses different content directories for each of the languages. Each language's content directory is set using the `contentDir` param. {{< code-toggle file="config" >}} languages: en: weight: 10 languageName: "English" contentDir: "content/english" fr: weight: 20 languageName: "Français" contentDir: "content/french" {{< /code-toggle >}} The value of `contentDir` can be any valid path -- even absolute path references. The only restriction is that the content directories cannot overlap. Considering the following example in conjunction with the configuration above: 1. `/content/english/about.md` 2. `/content/french/about.md` The first file is assigned the English language and is linked to the second. The second file is assigned the French language and is linked to the first. Their language is __assigned__ according to the content directory they are __placed__ in. By having the same **path and basename** (relative to their language content directory), the content pieces are __linked__ together as translated pages. ### Bypassing default linking. Any pages sharing the same `translationKey` set in front matter will be linked as translated pages regardless of basename or location. Considering the following example: 1. `/content/about-us.en.md` 2. `/content/om.nn.md` 3. `/content/presentation/a-propos.fr.md` ```yaml # set in all three pages translationKey: "about" ``` By setting the `translationKey` front matter param to `about` in all three pages, they will be __linked__ as translated pages. ### Localizing permalinks Because paths and filenames are used to handle linking, all translated pages will share the same URL (apart from the language subdirectory). To localize the URLs, the [`slug`]({{< ref "/content-management/organization/index.md#slug" >}}) or [`url`]({{< ref "/content-management/organization/index.md#url" >}}) front matter param can be set in any of the non-default language file. For example, a French translation (`content/about.fr.md`) can have its own localized slug. {{< code-toggle >}} Title: A Propos slug: "a-propos" {{< /code-toggle >}} At render, Hugo will build both `/about/` and `/fr/a-propos/` while maintaining their translation linking. {{% note %}} If using `url`, remember to include the language part as well: `/fr/compagnie/a-propos/`. {{%/ note %}} ### Page Bundles To avoid the burden of having to duplicate files, each Page Bundle inherits the resources of its linked translated pages' bundles except for the content files (markdown files, html files etc...). Therefore, from within a template, the page will have access to the files from all linked pages' bundles. If, across the linked bundles, two or more files share the same basename, only one will be included and chosen as follows: * File from current language bundle, if present. * First file found across bundles by order of language `Weight`. {{% note %}} Page Bundle resources follow the same language assignment logic as content files, both by filename (`image.jpg`, `image.fr.jpg`) and by directory (`english/about/header.jpg`, `french/about/header.jpg`). {{%/ note %}} ## Reference the Translated Content To create a list of links to translated content, use a template similar to the following: {{< code file="layouts/partials/i18nlist.html" >}} {{ if .IsTranslated }}