EmDash の管理画面 UI は翻訳可能で、メッセージの抽出には Lingui、翻訳の進捗管理には Lunaria を使用しています。すべての翻訳は、ロケールごとに 1 つの PO(gettext)ファイルに保存されます。
翻訳状況
すべてのロケールの現在の進捗は、翻訳ダッシュボードで確認できます。
翻訳できる人
すべての翻訳は、ネイティブスピーカーまたは流暢な話者が監修する必要があります。AI が生成した翻訳も受け付けますが、流暢な話者がすべての文字列をレビューし、提出前に実際に動作している管理パネルでプレビューした場合に限ります。監修されていない機械出力は受け付けません。以下の AI 支援翻訳と翻訳のテストを参照してください。
文字列を誤って翻訳するより、翻訳せずに残すほうが望ましいです。誤訳はユーザーを惑わせますが、英語のフォールバックは不便なだけです。
ファイル構造
翻訳カタログは packages/admin/src/locales/ にあります。
packages/admin/src/locales/
├── en/
│ └── messages.po # English (source)
├── de/
│ └── messages.po # German
└── ...
各 .po ファイルには msgid/msgstr のペアが含まれます。msgid は英語の原文、msgstr はあなたの翻訳です。msgstr が空の場合は「未翻訳」を意味し、Lingui は実行時に英語にフォールバックします。
文字列の翻訳
-
翻訳ダッシュボードを確認して、対応が必要な箇所を把握します。作業の重複を避けるため、オープン中の PR も確認してください。
-
リポジトリをフォークし、ブランチを作成します。
git checkout -b i18n/de -
自分のロケールの PO ファイルを開きます(例:
packages/admin/src/locales/de/messages.po)。 -
翻訳を入力します。 各エントリーは次のような形式です。
#: packages/admin/src/components/LoginPage.tsx:304 msgid "Sign in with Passkey" msgstr ""msgstrを埋めます。#: packages/admin/src/components/LoginPage.tsx:304 msgid "Sign in with Passkey" msgstr "Mit Passkey anmelden" -
翻訳をテストします(下記参照)。
-
mainを対象に PR を作成します。 タイトルの形式はi18n(de): add/update German translationsです。PR には、PO ファイル、changeset、そして新しい言語の追加で説明するロケール関連ファイルだけを含めてください。それ以外を変更した翻訳 PR には、自動化によってコメントが付きます。
翻訳すべきもの
- 各エントリーの
msgstrの値。
翻訳してはいけないもの
msgidの値。これらは検索用のキーです。{error}、{email}、{label}などの補間プレースホルダー。そのまま保持してください。<0>、</0>などの XML 風タグ。これらはインタラクティブな要素(リンク、ボタン)を囲みます。タグはそのまま残し、タグの間のテキストを翻訳してください。#:で始まるコメント。これらは Lingui が追加するソース参照です。
補間とタグ
一部の文字列には、プレースホルダーとタグが含まれます。
msgid "Authentication error: {error}"
msgstr "Authentifizierungsfehler: {error}"
msgid "Don't have an account? <0>Sign up</0>"
msgstr "Noch kein Konto? <0>Registrieren</0>"
msgid "If an account exists for <0>{email}</0>, we've sent a sign-in link."
msgstr "Falls ein Konto für <0>{email}</0> existiert, haben wir einen Anmeldelink gesendet."
プレースホルダー({error}、{email})は、実行時に動的な値に置き換えられます。タグ(<0>...</0>)は React コンポーネントを囲みます。どちらも、翻訳文に原文とまったく同じ形で含める必要があります。名前も入れ子構造も同じにしてください。
翻訳のテスト
-
コンパイルして、デモを実行します。
pnpm run locale:compile pnpm build pnpm --filter emdash-demo dev -
管理画面の設定ページでロケールを切り替え、翻訳が文脈の中で正しく見えることを確認します。
疑似ロケール
EmDash には疑似ロケールが含まれており、ラップされたすべての文字列をアクセント付きの似た文字に変換します。たとえば "Dashboard" は "Ðàšĥƀöàřð" になります。疑似ロケールが有効なときに通常の英語で表示される文字列は、t\…“ ラッパーが欠けているか、カタログの外から来ています。
有効にするには、デモディレクトリの .env ファイルに次を追加します。
EMDASH_PSEUDO_LOCALE=1
その後、開発サーバーを再起動します。疑似ロケールは、ログインページと設定の言語ピッカーに Pseudo として表示されます。切り替えると、ラップされていない文字列がひと目でわかります。
新しい言語の追加
お使いの言語にまだ PO ファイルがない場合は、次の手順に従います。
-
packages/admin/src/locales/locales.tsにロケールを追加します。export const LOCALES: LocaleDefinition[] = [ { code: "en", label: "English", enabled: true }, // ... { code: "vi", label: "Tiếng Việt", enabled: false, dateLocale: () => import("react-day-picker/locale/vi").then((m) => m.vi), }, ];dateLocaleは、お使いの言語向けのカレンダーと日付形式のローカライズを読み込みます。react-day-picker/localeの中で最も近いファイルを選びます(pt-PTならptなど)。そのファイルで名前が付けられているエクスポートを使用してください。お使いの言語が米国英語のカレンダーを使う場合に限り、省略できます。これが唯一の信頼できる情報源です。
lingui.config.ts、lunaria.config.ts、管理画面のランタイムは、いずれもこのファイルからロケール一覧を導き出します。翻訳作業中はenabled: falseにしておいてください。管理画面 UI で使用できる十分なカバレッジに達したら、メンテナーがそのロケールを有効にします。 -
抽出を実行して、空の PO ファイルを生成します。
pnpm run locale:extractこれにより、翻訳可能なすべての文字列を含む
packages/admin/src/locales/{your-locale}/messages.poが作成されます。 -
上記の手順に従って翻訳とテストを行います。
翻訳基準
正確性
翻訳は、ネイティブスピーカーのレベルで英語の原文を忠実に表現する必要があります。意味を追加したり、削除したり、解釈し直したりしないでください。原文が曖昧な場合は、#: コメントでソースファイルの場所を確認し、コンポーネントのコードを読んで文脈を理解してください。
一貫性
ロケール内で用語を統一してください。たとえば、ある箇所で “collection” を「Sammlung」と訳したなら、別の箇所で「Kollektion」に変えないでください。お使いの言語にすでに翻訳がある場合は、作業を始める前に既存の PO ファイルを読み、確立された用語に合わせてください。
トーン
管理画面 UI は、率直でプロフェッショナルなトーンを使います。お使いの言語でも同じトーンに合わせ、過度にかしこまった表現や過度にくだけた表現は避けてください。
AI 支援翻訳
最初の全文ドラフトを含め、AI ツールで翻訳を生成してもかまいませんが、流暢な話者が結果を監修する必要があります。
- 流暢な話者は、すべての文字列を必ずレビューしてください。AI ツールは、流暢な話者にしか気づけない細かな間違い(不適切な文体、不自然な言い回し、誤った専門用語)を起こします。
- 流暢な話者は、実際に動作している管理画面 UI で翻訳を必ずプレビューしてください。AI ツールは、レイアウトの制約や UI の文脈を認識していません。
- PR の説明文で AI を使用したことを明記してください。
- 監修されていない機械翻訳を含む PR はクローズされます。
部分翻訳
部分的な翻訳も歓迎します。1 つの PR ですべての文字列を翻訳する必要はありません。少しでも進めば助けになります。未翻訳の文字列は、実行時に英語にフォールバックします。