Skip to main content
Version: 2.0.0-beta.7 🚧

i18n - Tutorial

This tutorial will walk you through the basis of the Docusaurus i18n system.

We will add French translations to a newly initialized English Docusaurus website.

Initialize a new site with npx @docusaurus/init@latest init website classic (like this one).

Configure your site#

Modify docusaurus.config.js to add the i18n support for the French language.

Site configuration#

Use the site i18n configuration to declare the i18n locales:

docusaurus.config.js
module.exports = {  i18n: {    defaultLocale: 'en',    locales: ['en', 'fr'],  },};

Theme configuration#

Add a navbar item of type localeDropdown so that users can select the locale they want:

docusaurus.config.js
module.exports = {  themeConfig: {    navbar: {      items: [        {          type: 'localeDropdown',          position: 'left',        },      ],    },  },};

Start your site#

Start your localized site in dev mode, using the locale of your choice:

npm run start -- --locale fr

Your site is accessible at http://localhost:3000/fr/.

We haven't provided any translation, and the site is mostly untranslated.

tip

Docusaurus provides default translations for generic theme labels, such as "Next" and "Previous" for the pagination.

Please help us complete those default translations.

caution

Each locale is a distinct standalone single-page-application: it is not possible to start the Docusaurus sites in all locales at the same time.

Translate your site#

The French translations will be added in website/i18n/fr.

Docusaurus is modular, and each content plugin has its own subfolder.

note

After copying files around, restart your site with npm run start -- --locale fr.

Hot-reload will work better when editing existing files.

Use the translation APIs#

Open the homepage, and use the translation APIs:

src/pages/index.js
import React from 'react';import Layout from '@theme/Layout';import Link from '@docusaurus/Link';
import Translate, {translate} from '@docusaurus/Translate';
export default function Home() {  return (    <Layout>      <h1>        <Translate>Welcome to my website</Translate>      </h1>      <main>        <Translate          id="homepage.visitMyBlog"          description="The homepage message to ask the user to visit my blog"          values={{blog: <Link to="https://docusaurus.io/blog">blog</Link>}}>          {'You can also visit my {blog}'}        </Translate>
        <input          type="text"          placeholder={            translate({              message: 'Hello',              description: 'The homepage input placeholder',            })          }        />      </main>    </Layout>  );}
caution

Docusaurus provides a very small and lightweight translation runtime on purpose, and only supports basic placeholders interpolation, using a subset of the ICU Message Format.

Most documentation websites are generally static and don't need advanced i18n features (plurals, genders, etc.). Use a library like react-intl for more advanced use-cases.

Translate JSON files#

JSON translation files are used for everything that is not contained in a Markdown document:

  • React/JSX code
  • Layout navbar and footer labels
  • Docs sidebar category labels
  • ...

Run the write-translations command:

npm run write-translations -- --locale fr

It will extract and initialize the JSON translation files that you need to translate.

The homepage translations are statically extracted from React source code:

i18n/fr/code.json
{  "Welcome to my website": {    "message": "Welcome to my website",    "description": "The homepage welcome message"  },  "Hello": {    "message": "Hello",    "description": "The homepage input placeholder"  }}

Plugins and themes will also write their own JSON translation files, such as:

i18n/fr/docusaurus-theme-classic/navbar.json
{  "title": {    "message": "My Site",    "description": "The title in the navbar"  },  "item.label.Docs": {    "message": "Docs",    "description": "Navbar item with label Docs"  },  "item.label.Blog": {    "message": "Blog",    "description": "Navbar item with label Blog"  },  "item.label.GitHub": {    "message": "GitHub",    "description": "Navbar item with label GitHub"  }}

Translate the message attribute in the JSON files of i18n/fr, and your site layout and homepage should now be translated.

Translate Markdown files#

Official Docusaurus content plugins extensively use Markdown/MDX files, and allow you to translate them.

Translate the docs#

Copy your docs Markdown files to i18n/fr/docusaurus-plugin-content-docs/current, and translate them:

mkdir -p i18n/fr/docusaurus-plugin-content-docs/currentcp -r docs/** i18n/fr/docusaurus-plugin-content-docs/current
info

current is needed for the docs versioning feature: each docs version has its own subfolder.

Translate the blog#

Copy your blog Markdown files to i18n/fr/docusaurus-plugin-content-blog, and translate them:

mkdir -p i18n/fr/docusaurus-plugin-content-blogcp -r blog/** i18n/fr/docusaurus-plugin-content-blog

Translate the pages#

Copy your pages Markdown files to i18n/fr/docusaurus-plugin-content-pages, and translate them:

mkdir -p i18n/fr/docusaurus-plugin-content-pagescp -r src/pages/**.md i18n/fr/docusaurus-plugin-content-pagescp -r src/pages/**.mdx i18n/fr/docusaurus-plugin-content-pages
caution

We only copy .md and .mdx files, as pages React components are translated through JSON translation files already.

Use explicit heading ids#

By default, a Markdown heading ### Hello World will have a generated id hello-world.

Other documents can target it with [link](#hello-world).

The translated heading becomes ### Bonjour le Monde, with id bonjour-le-monde.

Generated ids are not always a good fit for localized sites, as it requires you to localize all the anchor links:

- [link](#hello-world).+ [link](#bonjour-le-monde)
tip

For localized sites, it is recommended to use explicit heading ids.

Deploy your site#

You can choose to deploy your site under a single domain, or use multiple (sub)domains.

Single-domain deployment#

Run the following command:

npm run build

Docusaurus will build one single-page application per locale:

  • website/build: for the default, English language
  • website/build/fr: for the French language

You can now deploy the build folder to the static hosting solution of your choice.

note

The Docusaurus v2 website use this strategy:

tip

Static hosting providers generally redirect /unknown/urls to /404.html by convention, always showing an English 404 page.

Localize your 404 pages by configuring your host to redirect /fr/* to /fr/404.html.

This is not always possible, and depends on your host: GitHub Pages can't do this, Netlify can.

Multi-domain deployment#

You can also build your site for a single locale:

npm run build -- --locale fr

Docusaurus will not add the /fr/ URL prefix.

On your static hosting provider:

  • create one deployment per locale
  • configure the appropriate build command, using the --locale option
  • configure the (sub)domain of your choice for each deployment
caution

This strategy is not possible with Github Pages, as it is only possible to have a single deployment.

Hybrid#

It is possible to have some locales using sub-paths, and others using subdomains.

It is also possible to deploy each locale as a separate subdomain, assemble the subdomains in a single unified domain at the CDN level:

  • Deploy your site as fr.docusaurus.io
  • Configure a CDN to serve it from docusaurus.io/fr