跳至主要內容
版本:3.5.2

i18n - 使用 Crowdin

Docusaurus 的 i18n 系統 與任何翻譯軟體脫鉤

只要你將 翻譯檔案放置在正確位置,你就可以將 Docusaurus 與 你選擇的工具和 SaaS 整合

我們記錄了 Crowdin 的用法,作為一個可能的整合範例

警告

並非認可 Crowdin 為翻譯 Docusaurus 網站的唯一選擇,但它已成功地被 Facebook 用於翻譯文件專案,例如 JestDocusaurusReasonML

有關協助,請參考Crowdin 文件Crowdin 支援

提示

使用這個由社群驅動的 GitHub 討論來討論任何與 Docusaurus + Crowdin 相關的主題。

Crowdin 概觀

Crowdin 是一種提供翻譯 SaaS 服務,其對開源專案提供免費方案

我們建議進行下列翻譯工作流程

  • 上傳來源至 Crowdin(未翻譯檔案)
  • 使用 Crowdin 翻譯內容
  • 下載翻譯檔案自 Crowdin(已在地化翻譯檔案)

Crowdin 提供上傳來源下載翻譯檔案CLI,讓您能自動化翻譯流程。

crowdin.yml 組態檔對於 Docusaurus 很方便,且允許在預期的位置(i18n/[地區代碼]/.. 中)下載在地化翻譯檔案

閱讀官方文件以瞭解進階功能和不同的翻譯工作流程。

Crowdin 教學

以下為使用 Crowdin 將新初始化的英文 Docusaurus 網站翻譯成法文的範例,並假設您已追蹤i18n 教學

最終成果可以在 docusaurus-crowdin-example.netlify.app儲存庫)中看見。

準備 Docusaurus 網站

初始化一個新 Docusaurus 網站

npx create-docusaurus@latest website classic

加入法語網站組態

docusaurus.config.js
export default {
i18n: {
defaultLocale: 'en',
locales: ['en', 'fr'],
},
themeConfig: {
navbar: {
items: [
// ...
{
type: 'localeDropdown',
position: 'left',
},
// ...
],
},
},
// ...
};

翻譯首頁

src/pages/index.js
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 註冊並建立專案。

使用英語作為源語言,法語作為目標語言。

Create a Crowdin project with english as source language, and french as target language

您的專案已建立,但目前為空。我們將在後續步驟中上傳要翻譯的文件。

建立 Crowdin 組態

這個組態 (文件) 提供巨集對應,以便 Crowdin CLI 能了解

  • 在哪裡找到要上傳的原始檔案 (JSON 和 Markdown)
  • 在翻譯後下載檔案的位置 (在 i18n/[地區])

website 中建立 crowdin.yml

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 目標語言的兩字母變體 (本例中為 fr)
  • **/%original_file_name%:翻譯將保留原始資料夾/檔案層級結構
資訊

Crowdin CLI 警告並不總是容易理解。

我們建議您

  • 一次只變更一項
  • 在任何組態變更後重新上傳原始檔
  • 使用從 / 開始的路徑 (./ 無效)
  • 避免使用花俏的萬用字元模式,例如 /docs/**/*.(md|mdx) (無效)

存取權杖

api_token_env 屬性定義 Crowdin CLI 可讀取的環境變數名稱

您可以在 您的個人檔案頁面 上取得個人存取權杖

提示

您可以保留預設值 CROWDIN_PERSONAL_TOKEN,並將此環境變數在您的電腦和 CI 伺服器上設定為產生的存取權杖。

警告

個人存取權杖授與對所有 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 版本會持續運作。

將 Crowdin CLI 安裝為 Docusaurus 站台的 npm 套件

npm install @crowdin/cli@3

新增 crowdin 腳本

package.json
{
"scripts": {
// ...
"write-translations": "docusaurus write-translations",
"crowdin": "crowdin"
}
}

測試是否可以執行 Crowdin CLI

npm run crowdin -- --version

在電腦上設定 CROWDIN_PERSONAL_TOKEN 環境變數,讓 CLI 可以通過 Crowdin API 驗證。

提示

暫時可以在 crowdin.yml 中以 api_token: '我的代碼' 硬式編寫你的個人代碼。

上傳原始檔

website/i18n/en 中為預設語言產生 JSON 翻譯檔

npm run write-translations

上傳所有 JSON 和 Markdown 翻譯檔

npm run crowdin upload

Crowdin CLI uploading Docusaurus source files

你的原始檔現在可在 Crowdin 介面中看到:https://crowdin.com/project/<我的專案名稱>/settings#files

Crowdin UI showing Docusaurus source files

翻譯原始檔

https://crowdin.com/project/<我的專案名稱> 中,點選法文目標語言。

Crowdin UI showing French translation files

翻譯一些 Markdown 檔案。

Crowdin UI to translate a Markdown file

提示

使用「隱藏字串」來確定翻譯者不翻譯不應被翻譯的內容

  • 前端事項:idslugtags ...
  • 警告:::::::note:::tip ...

Crowdin UI hide string

翻譯一些 JSON 檔案。

Crowdin UI to translate a JSON file

資訊

JSON 翻譯檔的 description 屬性在 Crowdin 中可用來協助翻譯字串。

提示

預翻譯你的站台,並手動修正預翻譯錯誤(先在設定中啟用「全球翻譯記憶體」)。

先使用「隱藏字串」功能,因為 Crowdin 在預翻譯時過於樂觀。

下載翻譯

使用 Crowdin CLI 下載已翻譯的 JSON 及 Markdown 檔案。

npm run crowdin download

已翻譯的內容會下載到 i18n/fr

在法文區域設定中開啟你的站台

npm run start -- --locale fr

確認你的網站現在已翻譯成法文,網址為 https://127.0.0.1:3000/fr/

利用 CI 自動化

我們會組態 CI,讓它在建置時下載 Crowdin 翻譯並將它們保留在 Git 外部。

website/i18n 新增到 .gitignore

在 CI 中設定 CROWDIN_PERSONAL_TOKEN 環境變數。

建立 npm 腳本来 同步 Crowdin(萃取原始檔、上傳原始檔、下載翻譯)

package.json
{
"scripts": {
"crowdin:sync": "docusaurus write-translations && crowdin upload && crowdin download"
}
}

在建置 Docusaurus 網站之前,請在 CI 中呼叫 npm run crowdin:sync 指令碼。

提示

確保部署預覽快速無礙:請勿下載翻譯,並針對功能分支使用 npm run build -- --locale en

警告

Crowdin 無法妥善支援多個並行的上傳/下載:建議僅將翻譯納入正式部署,並保持部署預覽呈現未翻譯狀態。

進階 Crowdin 論題

MDX

警告

務必特別留意 MDX 文件中的 JSX 斷片!

Crowdin 不正式支援 MDX,但他們已新增.mdx 副檔名的支援,並將此類檔案解譯為 Markdown(而非純文字)。

MDX 問題

Crowdin 視 JSX 語法為嵌入式 HTML,並可能在下載翻譯時搞亂 JSX 標記,導致網站因 JSX 無效而無法建置。

使用簡單字串屬性的簡單 JSX 片段,例如 <Username name="Sebastien"/>,將運作良好;使用物件/陣列屬性的較複雜 JSX 片段,例如 <User person={{name: "Sebastien"}}/>,因其語法不似 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 提供 重複字串 設定。

Crowdin Duplicate Strings option setting

我們建議使用 隱藏,但理想的設定取決於不同版本之間的差異程度。

警告

不使用 隱藏 會導致在配額中累積大量的 原始字串,並影響價格。

多執行個體外掛程式

您需要為每個外掛程式執行個體設定翻譯檔案。

如果您有一個 id=ios 的文件外掛程式執行個體,您也需要設定這些原始檔案

  • website/ios
  • website/ios_versioned_docs(如果經過版本化)

維護您的網站

有時候,您會在 Git 上移除或重新命名來源檔案,Crowdin 會顯示 CLI 警告

Crowdin CLI: download translation warning

當您的來源重構時,您應使用 Crowdin UI 來手動更新您的 Crowdin 檔案

Crowdin UI: renaming a file

VCS(Git)整合

Crowdin 具有多種 VCS 整合,可用於 GitHub、GitLab、Bitbucket。

TL;DR

我們建議避開這些檔案。

能夠在 Git 和 Crowdin 中編輯翻譯並在兩個系統之間具有雙向同步會有所幫助。

實際上,由於以下原因,其並未非常可靠地運作

  • Crowdin -> Git 同步運作良好(透過拉取要求)
  • Git -> Crowdin 同步為手動(您必須按下按鈕)
  • Crowdin 用於將現有的 Markdown 翻譯與現有的 Markdown 來源配對所使用的啟發法並非 100% 可靠,且您必須在從 Git 進行任何同步後在 Crowdin UI 上驗證結果
  • 2 個使用者同時在 Git 和 Crowdin 上編輯可能會導致翻譯遺失
  • 它需要 crowdin.yml 檔案位於儲存庫的根目錄

脈絡翻譯

Crowdin 有一個脈絡翻譯功能。

警告

很不幸地,由於技術原因,它尚未能運作,但我們深信它可以解決。

Crowdin 使用技術 ID(例如 crowdin:id12345)取代 Markdown 字串,但過於積極,包括隱藏字串、搞亂前端、警告、JSX...

在地化編輯網址

當使用者瀏覽 /fr/doc1 頁面時,編輯按鈕會預設連結到 website/docs/doc1.md 上未在地化的文件。

您可能傾向使用 editUrl 函數在每個區域的基礎上自訂編輯網址,將編輯按鈕連結到 Crowdin 介面。

docusaurus.config.js
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 設定檔是使用版本管理和多個執行個體的範例

crowdin.yml
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 搭配使用,您應該考慮這一點。