mirror of
https://github.com/facebook/docusaurus.git
synced 2025-05-02 11:47:23 +02:00
336 lines
9.3 KiB
Markdown
336 lines
9.3 KiB
Markdown
---
|
|
id: tutorial
|
|
title: i18n - Tutorial
|
|
slug: /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 create-docusaurus@latest website classic` (like [this one](https://github.com/facebook/docusaurus/tree/main/examples/classic)).
|
|
|
|
## Configure your site {#configure-your-site}
|
|
|
|
Modify `docusaurus.config.js` to add the i18n support for the French language.
|
|
|
|
### Site configuration {#site-configuration}
|
|
|
|
Use the [site i18n configuration](./../api/docusaurus.config.js.md#i18n) to declare the i18n locales:
|
|
|
|
```js title="docusaurus.config.js"
|
|
module.exports = {
|
|
i18n: {
|
|
defaultLocale: 'en',
|
|
locales: ['en', 'fr'],
|
|
},
|
|
};
|
|
```
|
|
|
|
### Theme configuration {#theme-configuration}
|
|
|
|
Add a **navbar item** of type `localeDropdown` so that users can select the locale they want:
|
|
|
|
```js title="docusaurus.config.js"
|
|
module.exports = {
|
|
themeConfig: {
|
|
navbar: {
|
|
items: [
|
|
// highlight-start
|
|
{
|
|
type: 'localeDropdown',
|
|
position: 'left',
|
|
},
|
|
// highlight-end
|
|
],
|
|
},
|
|
},
|
|
};
|
|
```
|
|
|
|
### Start your site {#start-your-site}
|
|
|
|
Start your localized site in dev mode, using the locale of your choice:
|
|
|
|
```bash npm2yarn
|
|
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](https://github.com/facebook/docusaurus/tree/main/packages/docusaurus-theme-translations/locales)**.
|
|
|
|
:::
|
|
|
|
:::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 {#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 {#use-the-translation-apis}
|
|
|
|
Open the homepage, and use the [translation APIs](../docusaurus-core.md#translate):
|
|
|
|
```jsx title="src/pages/index.js"
|
|
import React from 'react';
|
|
import Layout from '@theme/Layout';
|
|
import Link from '@docusaurus/Link';
|
|
|
|
// highlight-start
|
|
import Translate, {translate} from '@docusaurus/Translate';
|
|
// highlight-end
|
|
|
|
export default function Home() {
|
|
return (
|
|
<Layout>
|
|
<h1>
|
|
{/* highlight-start */}
|
|
<Translate>Welcome to my website</Translate>
|
|
{/* highlight-end */}
|
|
</h1>
|
|
<main>
|
|
{/* highlight-start */}
|
|
<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>
|
|
{/* highlight-end */}
|
|
|
|
<input
|
|
type="text"
|
|
placeholder={
|
|
// highlight-start
|
|
translate({
|
|
message: 'Hello',
|
|
description: 'The homepage input placeholder',
|
|
})
|
|
// highlight-end
|
|
}
|
|
/>
|
|
</main>
|
|
</Layout>
|
|
);
|
|
}
|
|
```
|
|
|
|
:::caution
|
|
|
|
Docusaurus provides a **very small and lightweight translation runtime** on purpose, and only supports basic [placeholders interpolation](../docusaurus-core.md#interpolate), using a subset of the [ICU Message Format](https://formatjs.io/docs/core-concepts/icu-syntax/).
|
|
|
|
Most documentation websites are generally **static** and don't need advanced i18n features (**plurals**, **genders**, etc.). Use a library like [react-intl](https://www.npmjs.com/package/react-intl) for more advanced use-cases.
|
|
|
|
:::
|
|
|
|
### Translate JSON files {#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](../cli.md#docusaurus-write-translations-sitedir) command:
|
|
|
|
```bash npm2yarn
|
|
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:
|
|
|
|
```json title="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:
|
|
|
|
```json title="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 {#translate-markdown-files}
|
|
|
|
Official Docusaurus content plugins extensively use Markdown/MDX files, and allow you to translate them.
|
|
|
|
#### Translate the docs {#translate-the-docs}
|
|
|
|
Copy your docs Markdown files to `i18n/fr/docusaurus-plugin-content-docs/current`, and translate them:
|
|
|
|
```bash
|
|
mkdir -p i18n/fr/docusaurus-plugin-content-docs/current
|
|
cp -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 {#translate-the-blog}
|
|
|
|
Copy your blog Markdown files to `i18n/fr/docusaurus-plugin-content-blog`, and translate them:
|
|
|
|
```bash
|
|
mkdir -p i18n/fr/docusaurus-plugin-content-blog
|
|
cp -r blog/** i18n/fr/docusaurus-plugin-content-blog
|
|
```
|
|
|
|
#### Translate the pages {#translate-the-pages}
|
|
|
|
Copy your pages Markdown files to `i18n/fr/docusaurus-plugin-content-pages`, and translate them:
|
|
|
|
```bash
|
|
mkdir -p i18n/fr/docusaurus-plugin-content-pages
|
|
cp -r src/pages/**.md i18n/fr/docusaurus-plugin-content-pages
|
|
cp -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 {#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:
|
|
|
|
```diff
|
|
- [link](#hello-world).
|
|
+ [link](#bonjour-le-monde)
|
|
```
|
|
|
|
:::tip
|
|
|
|
For localized sites, it is recommended to use **[explicit heading ids](../guides/markdown-features/markdown-features-headings.mdx#explicit-ids)**.
|
|
|
|
:::
|
|
|
|
## Deploy your site {#deploy-your-site}
|
|
|
|
You can choose to deploy your site under a **single domain**, or use **multiple (sub)domains**.
|
|
|
|
### Single-domain deployment {#single-domain-deployment}
|
|
|
|
Run the following command:
|
|
|
|
```bash npm2yarn
|
|
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](../deployment.mdx) the `build` folder to the static hosting solution of your choice.
|
|
|
|
:::note
|
|
|
|
The Docusaurus v2 website use this strategy:
|
|
|
|
- [https://docusaurus.io](https://docusaurus.io)
|
|
- [https://docusaurus.io/fr](https://docusaurus.io/fr)
|
|
|
|
:::
|
|
|
|
:::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](https://docs.netlify.com/routing/redirects/redirect-options/#custom-404-page-handling) can.
|
|
|
|
:::
|
|
|
|
### Multi-domain deployment {#multi-domain-deployment}
|
|
|
|
You can also build your site for a single locale:
|
|
|
|
```bash npm2yarn
|
|
npm run build -- --locale fr
|
|
```
|
|
|
|
Docusaurus will not add the `/fr/` URL prefix.
|
|
|
|
On your [static hosting provider](../deployment.mdx):
|
|
|
|
- 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 {#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`
|