本文へスキップ
バージョン: 3.5.2

i18n - チュートリアル

このチュートリアルでは、Docusaurus の i18n システムの基本について説明します。

新しく初期化された英語の Docusaurus ウェブサイトフランス語の翻訳を追加します。

npx create-docusaurus@latest website classic を使用して新しいサイトを初期化します(こちらを参照)。

サイトの設定

フランス語の i18n サポートを追加するために、docusaurus.config.js を変更します。

サイト設定

サイトの i18n 設定を使用して、i18n ローケールを宣言します。

docusaurus.config.js
export default {
i18n: {
defaultLocale: 'en',
locales: ['en', 'fr', 'fa'],
localeConfigs: {
en: {
htmlLang: 'en-GB',
},
// You can omit a locale (e.g. fr) if you don't need to override the defaults
fa: {
direction: 'rtl',
},
},
},
};

ロケール名は、翻訳ファイルの場所と、翻訳されたロケールのベース URL の両方に使用されます。すべてのロケールをビルドする場合、デフォルトのロケールのみがベース URL で名前が省略されます。

Docusaurus は、ロケール名を使用して適切なデフォルト値<html lang="..."> 属性、ロケールラベル、カレンダー形式など)を提供します。これらのデフォルト値は、localeConfigs でカスタマイズできます。

テーマ設定

ユーザーが目的のロケールを選択できるように、localeDropdown タイプのナビゲーションバー項目を追加します。

docusaurus.config.js
export default {
themeConfig: {
navbar: {
items: [
{
type: 'localeDropdown',
position: 'left',
},
],
},
},
};
ヒント

ユーザーがドロップダウンを使用してロケールを変更したときに URL に追加されるクエリパラメーターを渡すことができます(例:queryString: '?persistLocale=true')。

これは、サーバーで自動ロケール検出を実装するのに役立ちます。たとえば、このパラメーターを使用して、ユーザーの優先ロケールを Cookie に保存できます。

サイトの起動

選択したロケールを使用して、ローカライズされたサイトを開発モードで起動します。

npm run start -- --locale fr

サイトは http://localhost:3000/fr/ でアクセスできます。

まだ翻訳を提供していないため、サイトはほとんど翻訳されていません。

ヒント

Docusaurus は、ページャーの「次へ」や「前へ」など、一般的なテーマラベルのデフォルトの翻訳を提供します。

これらのデフォルトの翻訳の完成にご協力ください。

警告

各ロケールは、個別のスタンドアロンのシングルページアプリケーションです。すべてのロケールで Docusaurus サイトを同時に起動することはできません。

サイトの翻訳

フランス語ロケールのすべての翻訳データは、website/i18n/fr に保存されています。各プラグインは、対応するフォルダーの下で独自の翻訳済みコンテンツをソースとして使用し、code.json ファイルは React コードで使用されるすべてのテキストラベルを定義します。

注記

ファイルをコピーした後は、npm run start -- --locale fr でサイトを再起動します。既存のファイルを編集する場合は、ホットリロードがより効果的に機能します。

React コードの翻訳

自分で記述した React コード(React ページ、React コンポーネントなど)については、翻訳 API を使用します。

ユーザーに表示される React コード内のすべてのテキストラベルを見つけ、翻訳 API を使用してマークします。API には 2 つの種類があります。

  • <Translate> コンポーネントは、文字列を JSX 要素としてラップします。
  • translate() コールバックはメッセージを受け取り、文字列を返します。

セマンティックにコンテキストに最適な方を使用します。たとえば、<Translate> は React の子として使用できますが、文字列を期待するプロパティの場合は、コールバックを使用できます。

警告

JSX 要素はオブジェクトであり、文字列ではありません。<option>の子など、文字列を期待するコンテキストで使用すると、文字列に変換され、"[object Object]" が返されます。JSX 子として <Translate> を使用することをお勧めしますが、実際に機能する場合にのみ要素形式を使用してください。

src/pages/index.js
import React from 'react';
import Layout from '@theme/Layout';
import Link from '@docusaurus/Link';

export default function Home() {
return (
<Layout>
<h1>Welcome to my website</h1>
<main>
You can also visit my
<Link to="https://docusaurus.dokyumento.jp/blog">blog</Link>
<img
src="/img/home.png"
alt="Home icon"
/>
</main>
</Layout>
);
}
情報

Docusaurus は、意図的に非常に小さく軽量な翻訳ランタイムを提供しており、プレースホルダー補間の基本的なもののみをサポートしており、ICU メッセージ形式のサブセットを使用しています。

ほとんどのドキュメントウェブサイトは一般的に静的であり、高度な i18n 機能(複数形など)は必要ありません。より高度なユースケースには、react-intl などのライブラリを使用してください。

docusaurus write-translations コマンドは、サイトで使用されているすべての React コードファイルを静的に分析し、これらの API への呼び出しを抽出し、code.json ファイルに集約します。翻訳ファイルは、ID から翻訳済みメッセージオブジェクト(翻訳済みラベルとラベルの説明を含む)へのマップとして保存されます。翻訳 API(<Translate> または translate())への呼び出しでは、Docusaurus が各翻訳エントリを API 呼び出しに正しく関連付けるために、デフォルトの翻訳されていないメッセージまたは ID を指定する必要があります。

テキストラベルは静的である必要があります

docusaurus write-translations コマンドは、コードの静的分析のみを実行します。サイトを実際に実行しません。したがって、メッセージがではなく文字列であるため、動的なメッセージは抽出できません。

const items = [
{id: 1, title: 'Hello'},
{id: 2, title: 'World'},
];

function ItemsList() {
return (
<ul>
{/* DON'T DO THIS: doesn't work with the write-translations command */}
{items.map((item) => (
<li key={item.id}>
<Translate>{item.title}</Translate>
</li>
))}
<ul>
);
}

これは実行時には正しく動作しますが、将来は、ランタイムで API を呼び出す代わりに、Babel 変換を通じて翻訳を React コードに直接インライン化できる「ランタイムなし」メカニズムを提供する場合があります。したがって、将来に対応するために、常に静的に分析可能なメッセージを優先する必要があります。たとえば、上記のコードを次のようにリファクタリングできます。

const items = [
{id: 1, title: <Translate>Hello</Translate>},
{id: 2, title: <Translate>World</Translate>},
];

function ItemsList() {
return (
<ul>
{/* The titles are now already translated when rendering! */}
{items.map((item) => (
<li key={item.id}>{item.title}</li>
))}
<ul>
);
}

翻訳 API への呼び出しは、単なるマーカーであり、「翻訳済みメッセージで置き換えられるテキストラベルがあります」ということを Docusaurus に伝えるものです。

複数形

write-translations を実行すると、一部のラベルが複数形になっていることに気付くでしょう。

i18n/en/code.json
{
// ...
"theme.blog.post.plurals": "One post|{count} posts"
// ...
}

すべての言語には、可能な複数形カテゴリのリストがあります。Docusaurus は、それらを["zero", "one", "two", "few", "many", "other"] の順序で配置します。たとえば、英語(en)には 2 つの複数形(「one」と「other」)があるため、翻訳メッセージにはパイプ(|)で区切られた 2 つのラベルがあります。3 つの複数形(「one」、「few」、「many」)を持つポーランド語(pl)の場合、その順序で 3 つのラベルをパイプで区切って提供します。

独自のコードのメッセージも複数形にすることができます。

import {translate} from '@docusaurus/Translate';
import {usePluralForm} from '@docusaurus/theme-common';

function ItemsList({items}) {
// `usePluralForm` will provide the plural selector for the current locale
const {selectMessage} = usePluralForm();
// Select the appropriate pluralized label based on `items.length`
const message = selectMessage(
items.length,
translate(
{message: 'One item|{count} items'},
{count: items.length},
),
);
return (
<>
<h2>{message}</h2>
<ul>{items.map((item) => <li key={item.id}>{item.title}</li>)}<ul>
</>
);
}
注記

Docusaurus は、Intl.PluralRules を使用して複数形を解決および選択します。selectMessage が機能するには、正しい順序で適切な数の複数形を提供することが重要です。

プラグインデータの翻訳

JSON 翻訳ファイルは、コード中に散在するすべてのものに使用されます。

  • 上記でマークした翻訳済みのラベルを含むReactコード
  • テーマ設定ファイル内のナビゲーションバーとフッターのラベル
  • sidebars.jsファイル内のドキュメントサイドバーのカテゴリラベル
  • プラグインオプション内のブログサイドバーのタイトル
  • ...

write-translationsコマンドを実行します

npm run write-translations -- --locale fr

このコマンドは、翻訳に必要なJSON翻訳ファイルを抽出し、初期化します。ルートディレクトリのcode.jsonファイルには、ソースコードから抽出されたすべての翻訳API呼び出しが含まれています。これは、ユーザーが記述するか、テーマによって提供されるもので、その一部はデフォルトで既に翻訳されている場合があります。

i18n/fr/code.json
{
// No ID for the <Translate> component: the default message is used as ID
"Welcome to my website": {
"message": "Welcome to my website"
},
"home.visitMyBlog": {
"message": "You can also visit my {blog}",
"description": "The homepage message to ask the user to visit my blog"
},
"homepage.visitMyBlog.linkLabel": {
"message": "Blog",
"description": "The label for the link to my blog"
},
"Home icon": {
"message": "Home icon",
"description": "The homepage icon alt message"
}
}

プラグインとテーマも独自のJSON翻訳ファイルを作成します。例:

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"
}
}

i18n/fr内のJSONファイルのmessage属性を翻訳すると、サイトのレイアウトとホームページが翻訳されます。

Markdownファイルの翻訳

公式のDocusaurusコンテンツプラグインは、Markdown/MDXファイルを広く使用しており、それらの翻訳が可能です。

ドキュメントの翻訳

ドキュメントのMarkdownファイルをdocs/からi18n/fr/docusaurus-plugin-content-docs/currentにコピーして翻訳します

mkdir -p i18n/fr/docusaurus-plugin-content-docs/current
cp -r docs/** i18n/fr/docusaurus-plugin-content-docs/current
情報

docusaurus-plugin-content-docsプラグインは、常にコンテンツをバージョン別に分割することに注意してください。./docsフォルダのデータは、currentサブフォルダとcurrent.jsonファイルで翻訳されます。「current」の意味については、ドキュメントのバージョン管理ガイドを参照してください。

ブログの翻訳

ブログのMarkdownファイルをi18n/fr/docusaurus-plugin-content-blogにコピーして翻訳します

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

ページの翻訳

ページのMarkdownファイルをi18n/fr/docusaurus-plugin-content-pagesにコピーして翻訳します

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
警告

Reactページは既にJSON翻訳ファイルを通じて翻訳されているため、.md.mdxファイルのみをコピーします。

明示的な見出しIDを使用する

デフォルトでは、Markdownの見出し### Hello Worldには、hello-worldというIDが生成されます。他のドキュメントは、[link](#hello-world)でこれをリンクできます。しかし、翻訳後、見出しは### Bonjour le Mondeになり、IDはbonjour-le-mondeになります。

生成されたIDは、すべてのアンカーリンクをローカライズする必要があるため、ローカライズされたサイトには必ずしも適していません。

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

ローカライズされたサイトでは、明示的な見出しIDを使用することをお勧めします。

サイトのデプロイ

サイトを**単一ドメイン**でデプロイするか、**複数の(サブ)ドメイン**を使用するかを選択できます。

単一ドメインでのデプロイ

次のコマンドを実行します

npm run build

Docusaurusは、ロケールごとに**単一ページアプリケーションを1つビルド**します。

  • website/build:デフォルトの英語
  • website/build/fr:フランス語

これで、お好みの静的ホスティングソリューションにbuildフォルダをデプロイできます。

注記

Docusaurusウェブサイトはこの戦略を使用しています。

ヒント

静的ホスティングプロバイダーは、一般的に慣例により/unknown/url/404.htmlにリダイレクトするため、常に**英語の404ページ**が表示されます。

ホストの設定で/fr/*/fr/404.htmlにリダイレクトすることで、**404ページをローカライズ**します。

これは常に可能とは限らず、ホストによって異なります。GitHub Pagesではこれはできませんが、Netlifyでは可能です。

複数ドメインでのデプロイ

単一ロケール用のサイトをビルドすることもできます。

npm run build -- --locale fr

Docusaurusは/fr/URLプレフィックスを追加しません。

静的ホスティングプロバイダーで静的ホスティングプロバイダー

  • ロケールごとに1つのデプロイを作成します
  • --localeオプションを使用して、適切なビルドコマンドを設定します
  • 各デプロイに、選択した(サブ)ドメインを設定します
警告

この戦略は、**単一のデプロイメントしかできない**ため、GitHub Pagesでは**不可能**です。

ハイブリッド

サブパスを使用するロケールとサブドメインを使用するロケールを混在させることができます。

各ロケールを別々のサブドメインとしてデプロイし、CDNレベルで単一の統合ドメインにサブドメインを集約することも可能です。

  • サイトをfr.docusaurus.ioとしてデプロイします。
  • CDNを設定してdocusaurus.io/frから提供します。

翻訳の管理

Docusaurusは、翻訳の管理方法を気にしません。必要なのは、ビルド時にすべての翻訳ファイル(JSON、Markdown、その他のデータファイル)がファイルシステムで使用できることです。ただし、サイト作成者として、翻訳担当者が適切に協力できるように、翻訳の管理方法を検討する必要があります。

Gitの使用Crowdinの使用という2つの一般的な翻訳コラボレーション戦略を紹介します。