i18n - Crowdin の使用
Docusaurus の i18n システムは、**いかなる翻訳ソフトウェアからも独立しています**。
**正しい場所に翻訳ファイルを設置する**限り、Docusaurus をお好みの**ツールや SaaS と統合**できます。
Crowdin の使用方法を、**可能な統合例の一つ**として説明します。
これは、Docusaurus サイトの翻訳における唯一の選択肢として Crowdin を**推奨するものではありません**が、Facebook は Jest、Docusaurus、ReasonML などのドキュメントプロジェクトの翻訳に成功裏に使用しています。
ヘルプについては、**Crowdin のドキュメント** と **Crowdin のサポート** を参照してください。
Docusaurus + Crowdin に関するご質問は、**コミュニティ主導の GitHub ディスカッション** をご利用ください。
Crowdin の概要
Crowdin は翻訳 SaaS で、オープンソースプロジェクト向けの無料プランを提供しています。
次の翻訳ワークフローをお勧めします。
- Crowdin に**ソースをアップロード**する(翻訳されていないファイル)
- Crowdin を使用して**コンテンツを翻訳**する
- Crowdin から**翻訳をダウンロード**する(ローカライズされた翻訳ファイル)
Crowdin は、**ソースのアップロード**と**翻訳のダウンロード**を可能にするCLIを提供しており、翻訳プロセスを自動化できます。
crowdin.yml
設定ファイルは Docusaurus に便利で、**ローカライズされた翻訳ファイルを期待される場所にダウンロード**できます(i18n/[locale]/..
内)。
高度な機能やさまざまな翻訳ワークフローの詳細については、**公式ドキュメント** を参照してください。
Crowdin チュートリアル
これは、新しく初期化された英語の Docusaurus ウェブサイトをフランス語に翻訳するために Crowdin を使用する手順であり、i18n チュートリアルを既に完了していることを前提としています。
最終的な結果は docusaurus-crowdin-example.netlify.app(リポジトリ)で確認できます。
Docusaurus サイトの準備
新しい Docusaurus サイトを初期化する
npx create-docusaurus@latest website classic
フランス語のサイト設定を追加する
export default {
i18n: {
defaultLocale: 'en',
locales: ['en', 'fr'],
},
themeConfig: {
navbar: {
items: [
// ...
{
type: 'localeDropdown',
position: 'left',
},
// ...
],
},
},
// ...
};
ホームページを翻訳する
import React from 'react';
import Translate from '@docusaurus/Translate';
import Layout from '@theme/Layout';
export default function Home() {
return (
<Layout>
<h1 style={{margin: 20}}>
<Translate description="The homepage main heading">
Welcome to my Docusaurus translated site!
</Translate>
</h1>
</Layout>
);
}
Crowdin プロジェクトの作成
Crowdin にサインアップして、プロジェクトを作成します。
ソース言語に英語、ターゲット言語にフランス語を使用します。
プロジェクトは作成されましたが、現時点では空です。次の手順で翻訳するファイルをアップロードします。
Crowdin 設定の作成
この設定(doc)は、Crowdin CLI が理解するためのマッピングを提供します。
- アップロードするソースファイル(JSON と Markdown)の場所
- 翻訳後のファイルのダウンロード場所(
i18n/[locale]
内)
website
に crowdin.yml
を作成する
project_id: '123456'
api_token_env: CROWDIN_PERSONAL_TOKEN
preserve_hierarchy: true
files:
# JSON translation files
- source: /i18n/en/**/*
translation: /i18n/%two_letters_code%/**/%original_file_name%
# Docs Markdown files
- source: /docs/**/*
translation: /i18n/%two_letters_code%/docusaurus-plugin-content-docs/current/**/%original_file_name%
# Blog Markdown files
- source: /blog/**/*
translation: /i18n/%two_letters_code%/docusaurus-plugin-content-blog/**/%original_file_name%
Crowdin には、ソース/翻訳パスの宣言のための独自の構文があります。
**/*
:サブフォルダ内のすべて%two_letters_code%
:Crowdin ターゲット言語の 2 文字の変種(この場合はfr
)**/%original_file_name%
:翻訳では元のフォルダ/ファイルの階層が保持されます。
Crowdin CLI の警告は、常に理解しやすいわけではありません。
次のことをお勧めします。
- 一度に一つずつ変更する
- 設定を変更するたびにソースを再アップロードする
/
から始まるパスを使用する(./
は機能しません)/docs/**/*.(md|mdx)
のような高度なグロビングパターンは避ける(機能しません)
アクセストークン
api_token_env
属性は、Crowdin CLI によって読み取られる**環境変数の名前**を定義します。
個人プロファイルページでPersonal Access Token
を取得できます。
デフォルト値 CROWDIN_PERSONAL_TOKEN
を使用し、この環境変数をコンピューターと CI サーバーで生成されたアクセストークンに設定できます。
Personal Access Token は、**すべての Crowdin プロジェクトへの読み書きアクセス権**を付与します。
**コミットしないでください**。個人アカウントを使用する代わりに、専用の**企業向け Crowdin プロファイル**を作成することをお勧めします。
その他の設定フィールド
project_id
:ハードコードでき、https://crowdin.com/project/<MY_PROJECT_NAME>/settings#api
にあります。preserve_hierarchy
:ドキュメントのフォルダ階層を Crowdin UI 上で平坦化せずに保持します。
Crowdin CLI のインストール
このチュートリアルでは CLI バージョン 3.5.2
を使用していますが、3.x
リリースは引き続き動作する予定です。
npm パッケージとして Docusaurus サイトに Crowdin CLI をインストールします。
- npm
- Yarn
- pnpm
npm install @crowdin/cli@3
yarn add @crowdin/cli@3
pnpm add @crowdin/cli@3
crowdin
スクリプトを追加する
{
"scripts": {
// ...
"write-translations": "docusaurus write-translations",
"crowdin": "crowdin"
}
}
Crowdin CLI を実行できることをテストする
- npm
- Yarn
- pnpm
npm run crowdin -- --version
yarn crowdin --version
pnpm run crowdin --version
CLI が Crowdin API で認証できるように、コンピューターで CROWDIN_PERSONAL_TOKEN
環境変数を設定します。
一時的に、api_token: 'MY-TOKEN'
を使用して、個人トークンを crowdin.yml
にハードコードできます。
ソースのアップロード
website/i18n/en
にデフォルト言語の JSON 翻訳ファイルを作成する
- npm
- Yarn
- pnpm
npm run write-translations
yarn write-translations
pnpm run write-translations
すべての JSON と Markdown の翻訳ファイルをアップロードする
- npm
- Yarn
- pnpm
npm run crowdin upload
yarn crowdin upload
pnpm run crowdin upload
ソースファイルは、Crowdin インターフェース:https://crowdin.com/project/<MY_PROJECT_NAME>/settings#files
に表示されるようになりました。
ソースの翻訳
https://crowdin.com/project/<MY_PROJECT_NAME>
で、フランス語のターゲット言語をクリックします。
いくつかの Markdown ファイルを翻訳します。
文字列を非表示
を使用して、翻訳者が**翻訳すべきでないものを翻訳しない**ようにします。
- フロントマター:
id
、slug
、tags
など… - アドモニション:
:::
、:::note
、:::tip
など…
いくつかの JSON ファイルを翻訳します。
JSON 翻訳ファイルの description
属性は、文字列の翻訳に役立つように Crowdin に表示されます。
サイトを**事前翻訳**し、**事前翻訳のミスを手動で修正**します(最初に設定でグローバル翻訳メモリを有効にする)。
Crowdin は楽観的に物事を事前翻訳するため、最初に 文字列を非表示
機能を使用します。
翻訳のダウンロード
Crowdin CLI を使用して、翻訳された JSON と Markdown ファイルをダウンロードします。
- npm
- Yarn
- pnpm
npm run crowdin download
yarn crowdin download
pnpm run crowdin download
翻訳されたコンテンツは i18n/fr
にダウンロードされます。
フランス語ロケールでサイトを開始する
- npm
- Yarn
- pnpm
npm run start -- --locale fr
yarn run start --locale fr
pnpm run start --locale fr
ウェブサイトがフランス語に翻訳されていることを http://localhost:3000/fr/
で確認してください。
CI による自動化
CI を設定して、**ビルド時に Crowdin の翻訳をダウンロード**し、Git の外部に保持します。
website/i18n
を .gitignore
に追加します。
CI で CROWDIN_PERSONAL_TOKEN
環境変数を設定します。
Crowdinとの同期を行うnpmスクリプトを作成します(ソースの抽出、ソースのアップロード、翻訳のダウンロード)。
{
"scripts": {
"crowdin:sync": "docusaurus write-translations && crowdin upload && crowdin download"
}
}
CI内で、Docusaurusサイトのビルド直前に`npm run crowdin:sync`スクリプトを実行します。
デプロイプレビューを高速に保つため、翻訳をダウンロードせず、フィーチャーブランチには`npm run build -- --locale en`を使用します。
Crowdinは複数の同時アップロード/ダウンロードをうまくサポートしていません。本番環境へのデプロイには翻訳を含めるようにし、デプロイプレビューは翻訳なしにすることをお勧めします。
Crowdinに関する高度なトピック
MDX
MDXドキュメント内のJSXフラグメントに特に注意してください!
Crowdinは**公式にはMDXをサポートしていません**が、**`.mdx`拡張子のサポートを追加**しており、そのようなファイルをプレーンテキストではなくMarkdownとして解釈します。
MDXの問題
CrowdinはJSX構文を埋め込みHTMLだと考え、翻訳をダウンロードする際にJSXマークアップを混乱させる可能性があり、無効なJSXによりサイトのビルドが失敗する原因となります。
`<Username name="Sebastien"/>`のような単純な文字列プロパティを使用する単純なJSXフラグメントは問題なく動作しますが、`<User person={{name: "Sebastien"}}/>`のようなオブジェクト/配列プロパティを使用する複雑なJSXフラグメントは、HTMLのように見えない構文のため、失敗する可能性が高くなります。
MDXの解決策
複雑な埋め込みJSXコードを独立したスタンドアロンコンポーネントとして抽出することをお勧めします。また、`mdx-code-block`エスケープハッチ構文も追加しました。
# How to deploy Docusaurus
To deploy Docusaurus, run the following command:
````mdx-code-block
import Tabs from '@theme/Tabs';
import TabItem from '@theme/TabItem';
<Tabs>
<TabItem value="bash" label="Bash">
```bash
GIT_USER=<GITHUB_USERNAME> yarn deploy
```
</TabItem>
<TabItem value="windows" label="Windows">
```batch
cmd /C "set "GIT_USER=<GITHUB_USERNAME>" && yarn deploy"
```
</TabItem>
</Tabs>
````
これにより
- Crowdinではコードブロックとして解釈され(ダウンロード時のマークアップを混乱させません)、
- Docusaurusでは通常のJSXとして解釈されます(コードブロックでラップされていない場合と同様です)。
- 残念ながら、MDXツール(IDE構文の強調表示、Prettierなど)は使用できなくなります。
ドキュメントのバージョン管理
`website/versioned_docs`フォルダの翻訳ファイルを構成します。
新しいバージョンを作成する場合、ソース文字列は現在のバージョン(`website/docs`)と非常に似ていることが一般的であり、新しいバージョンのドキュメントを何度も翻訳する必要はありません。
Crowdinは`重複文字列`設定を提供しています。
`非表示`の使用をお勧めしますが、最適な設定はバージョン間の違いによって異なります。
`非表示`を使用しない場合、クォータ内の`ソース文字列`の量が大幅に増加し、価格に影響します。
複数インスタンスのプラグイン
各プラグインインスタンスの翻訳ファイルを構成する必要があります。
`id=ios`のドキュメントプラグインインスタンスがある場合、これらのソースファイルも構成する必要があります。
website/ios
- website/ios_versioned_docs(バージョン管理されている場合)
サイトの維持
Gitでソースファイルの削除または名前変更を行うと、CrowdinにCLI警告が表示される場合があります。
ソースがリファクタリングされた場合は、Crowdin UIを使用して**Crowdinファイルをマニュアルで更新**してください。
VCS(Git)統合
Crowdinには、GitHub、GitLab、Bitbucketの複数のVCS統合があります。
それらの使用は避けることをお勧めします。
GitとCrowdinの両方で翻訳を編集し、2つのシステム間で**双方向同期**を行うことができれば便利だったでしょう。
実際には、いくつかの理由から**非常に信頼性が低かった**です。
- Crowdin -> Gitの同期は問題なく機能します(プルリクエストを使用)。
- Git -> Crowdinの同期は手動です(ボタンを押す必要があります)。
- 既存のMarkdown翻訳を既存のMarkdownソースに一致させるためにCrowdinで使用されるヒューリスティックは100%信頼できるものではなく、Gitからの同期後、Crowdin UIで結果を確認する必要があります。
- 2人のユーザーがGitとCrowdinで同時に編集すると、翻訳が失われる可能性があります。
- リポジトリのルートに`crowdin.yml`ファイルが必要です。
コンテキスト内ローカリゼーション
Crowdinにはコンテキスト内ローカリゼーション機能があります。
残念ながら、技術的な理由によりまだ機能していませんが、解決できることを期待しています。
CrowdinはMarkdown文字列を`crowdin:id12345`などの技術的なIDに置き換えますが、隠された文字列も含めて非常に積極的に行うため、フロントマター、注意書き、JSXなどが混乱します。
編集URLのローカライズ
ユーザーが`/fr/doc1`のページを参照している場合、編集ボタンはデフォルトで`website/docs/doc1.md`のローカライズされていないドキュメントにリンクします。
`editUrl`関数を使用してロケールごとに編集URLをカスタマイズすることにより、編集ボタンをCrowdinインターフェースにリンクすることを選択できます。
const DefaultLocale = 'en';
export default {
presets: [
[
'@docusaurus/preset-classic',
{
docs: {
editUrl: ({locale, versionDocsDirPath, docPath}) => {
// Link to Crowdin for French docs
if (locale !== DefaultLocale) {
return `https://crowdin.com/project/docusaurus-v2/${locale}`;
}
// Link to GitHub for English docs
return `https://github.com/facebook/docusaurus/edit/main/website/${versionDocsDirPath}/${docPath}`;
},
},
blog: {
editUrl: ({locale, blogDirPath, blogPath}) => {
if (locale !== DefaultLocale) {
return `https://crowdin.com/project/docusaurus-v2/${locale}`;
}
return `https://github.com/facebook/docusaurus/edit/main/website/${blogDirPath}/${blogPath}`;
},
},
},
],
],
};
現在、Crowdin内の特定のファイルへのリンクは**不可能**です。
設定例
**Docusaurus設定ファイル**は、バージョン管理と複数インスタンスの使用の良い例です。
project_id: '428890'
api_token_env: CROWDIN_PERSONAL_TOKEN
preserve_hierarchy: true
languages_mapping: &languages_mapping
two_letters_code:
pt-BR: pt-BR
files:
- source: /website/i18n/en/**/*
translation: /website/i18n/%two_letters_code%/**/%original_file_name%
languages_mapping: *languages_mapping
- source: /website/docs/**/*
translation: /website/i18n/%two_letters_code%/docusaurus-plugin-content-docs/current/**/%original_file_name%
languages_mapping: *languages_mapping
- source: /website/community/**/*
translation: /website/i18n/%two_letters_code%/docusaurus-plugin-content-docs-community/current/**/%original_file_name%
languages_mapping: *languages_mapping
- source: /website/versioned_docs/**/*
translation: /website/i18n/%two_letters_code%/docusaurus-plugin-content-docs/**/%original_file_name%
languages_mapping: *languages_mapping
- source: /website/blog/**/*
translation: /website/i18n/%two_letters_code%/docusaurus-plugin-content-blog/**/%original_file_name%
languages_mapping: *languages_mapping
- source: /website/src/pages/**/*
translation: /website/i18n/%two_letters_code%/docusaurus-plugin-content-pages/**/%original_file_name%
ignore: [/**/*.js, /**/*.jsx, /**/*.ts, /**/*.tsx, /**/*.css]
languages_mapping: *languages_mapping
機械翻訳(MT)の問題:リンク/画像の処理
Crowdinは最近、Markdownファイル形式に大きな変更を加え、リンクの扱いが以前とは異なります。以前はタグとして扱われていましたが、現在はプレーンテキストとして表示されます。これらの変更により、プレーンテキストのリンクがMTエンジンに渡され、ターゲットの翻訳が試みられ、翻訳が壊れます(例:`Allez voir [ma merveilleuse page](/ma-merveilleuse-page)`という文字列は`Check out [my wonderful page](/my-wonderful-page)`と翻訳され、ページ名は翻訳されないため、docusaurusのi18nワークフローが壊れます)。
2023年12月7日現在、リンクの処理方法のロジックを変更する予定はないため、CrowdinをMTで使用する場合、この点を考慮する必要があります。