国際化(i18n)
Apothem ドキュメントサイトが、12 の言語にわたって、ロケールコホートをどのように宣言し、hreflang の代替言語リンクをどのように出力し、右から左への表示をどのようにレンダリングするか。
このページでは、Apothem ドキュメントサイトが複数の言語をどのように扱うかを説明します。
すなわち、サイトが宣言するロケールコホート、出力する hreflang の仕組み、右から左へのレンダリング、そして各言語のページがどのようにルーティングに組み込まれるかです。
決定の要約
- プラットフォーム: Next.js App Router + Fumadocs。 サイトは
site/からビルドされます。 ロケールコホートはsite/lib/i18n.tsで宣言され、代替言語リンクの仕組みはsite/lib/hreflang.tsにあります。 - ロケールコホート: 12 言語。 12 ロケールからなる Modern Dev Cohort が正規の信頼できる情報源です。
英語がソースロケールであり、11 のターゲットはそれぞれ英語のページセットから機械翻訳によって初期生成されています。
ロケールごとの人によるレビューは進行中であり、ロケールがまだ作成していないページは
fallbackLanguage: 'en'がカバーします。 - ロケールごとのルーティング: コホート全体で有効。 すべてのロケールがルーティングに組み込まれ、それぞれの URL 接頭辞(
/es/、/zh-cn/、…)で到達できます。 英語はサイトのルートで配信されます。 hreflangの仕組み: 有効。 すべてのページは、各ロケールとx-defaultフォールバックを対象とする<link rel="alternate">のセットを出力するため、検索エンジンは代替言語のクラスター全体を認識できます。 リンクはファイルシステムからファイル単位で解決されるため、あるページがあるロケールで告知されるのは、そのロケールにそのページがある場合だけです。- 右から左へのレンダリング: 有効。 共有スタイルシートは全体を通じて論理 CSS プロパティを使用しているため、アラビア語のページは
dir="rtl"の下で正しくレンダリングされます。 - 翻訳のレビュー: ページごとに追跡。 機械翻訳で初期生成されたロケールページは配信され、人がレビューするまでフロントマターに
machineTranslated: trueを持ちます。このフラグはレビュー追跡用のメタデータであり、ページには表示されません。 ロケールにないページについては、英語がフォールバックになります。ロケールのページの 80% がレビュー済みであることはレビューの目標であり、公開の条件ではありません。 - 翻訳の鮮度: ページごとに追跡。 各ロケールページは、翻訳元の英語テキストを記録します。 後で英語ページが変更されると、翻訳されたページには英語ページへのリンクを含む 1 行の注記が表示されます。英語ページは引き続き権威を持ちます。
ロケールコホート
Modern Dev Cohort は 12 のロケールを宣言します。
英語はサイトのルートで配信されます。11 のターゲットはそれぞれ、英語のページセットから機械翻訳によって初期生成され、それぞれの URL 接頭辞の下で配信されます。まだ作成されていないページは fallbackLanguage: 'en' がカバーします。
| コード | パス | 言語 | 書字方向 |
|---|---|---|---|
en | / | 英語 | LTR |
zh-CN | /zh-cn/ | 簡体字中国語 | LTR |
es | /es/ | スペイン語 | LTR |
pt-BR | /pt-br/ | ブラジルポルトガル語 | LTR |
fr | /fr/ | フランス語 | LTR |
de | /de/ | ドイツ語 | LTR |
ja | /ja/ | 日本語 | LTR |
ko | /ko/ | 韓国語 | LTR |
ru | /ru/ | ロシア語 | LTR |
id | /id/ | インドネシア語 | LTR |
ar | /ar/ | アラビア語 | RTL |
hi | /hi/ | ヒンディー語 | LTR |
コホートは唯一の信頼できる情報源です。 その修正は意図的な決定を経て行われ、無言の編集によって行われることは決してありません。
hreflang の仕組み
site/lib/hreflang.ts は、Next.js が各ページの <head> へレンダリングする alternates.languages マップを構築します。
その構築は 1 つのルールに従います。あるロケールの代替言語リンクは、そのロケールがそのページを作成済みの場合にのみ出力され、これはファイルシステムからファイル単位で解決されます(site/lib/translated-pages.ts)。
そのため、完全に翻訳されたページは、クラスター全体を出力します。
<link rel="alternate" hreflang="en" href="https://apothem.ahmedgad.com/..." />
<link rel="alternate" hreflang="es" href="https://apothem.ahmedgad.com/es/..." />
<link rel="alternate" hreflang="ar" href="https://apothem.ahmedgad.com/ar/..." dir="rtl" />
<!-- … one per cohort locale … -->
<link rel="alternate" hreflang="x-default" href="https://apothem.ahmedgad.com/..." />ページの canonical リンクは、常にそのページ自身の URL です。ロケールをまたいで指すことは決してありません。
右から左へのレンダリング
アラビア語はコホートの中で右から左へ書くロケールであり、サイトはそれを正しくレンダリングします。
- 論理 CSS プロパティのみ。 共有スタイルシートとコンポーネントは、物理プロパティ(
margin-left、text-align: left)ではなく、論理プロパティ(margin-inline-start、padding-inline-end、text-align: start、inset-inline-start)を使用します。 論理プロパティはdir="rtl"の下で自動的に反転するため、同じスタイルシートが両方の方向を正しく扱います。 - 方向属性。 アラビア語のページは、
<html>要素にlang="ar"とともにdir="rtl"を設定します。 - 双方向コンテンツ。 方向が混在する文字列 — たとえばアラビア語の段落内にある英語のコマンド — は
<bdi>でラップされるため、埋め込まれた左から右への連なりが、右から左への流れの中で正しくレンダリングされます。
ロケールの追加または更新
コホートとルーティングは site/lib/i18n.ts によって駆動されます。
- 英語のソースを反映して、
content/docs/<locale>/配下にページを作成します。 - 翻訳元の英語テキストを記録します。
site/からnode scripts/translation-sources.mjs --stamp <locale>/<path>.mdxを実行すると、英語ページのハッシュがロケールページのsourceHashフロントマターに書き込まれます。 - ロケールが
ROUTED_LOCALESに記載されていることを確認します(現在、コホートの 12 ロケールすべてがルーティングされています)。 - その
hreflangリンクとルートは、ファイルシステムから自動的に解決されます。
古くなった翻訳
ロケールページの sourceHash は、翻訳元となった英語ページのハッシュです。英語のフロントマターと本文を対象としますが、リファレンスジェネレーターがすべての言語で一度に書き換える生成済みの表は対象外です。
ビルド時に、サイトは現在の英語ページのハッシュを計算します。2 つが異なる場合、翻訳されたページには、翻訳の作成後に英語ページが変更されたことを示す注記が、英語ページへのリンクとともに表示されます。
site/ から node scripts/translation-sources.mjs を実行してロケールごとに古くなったページを一覧表示し、その後、各翻訳を更新して、上記の手順 2 と同様にスタンプします。
あるロケールでまったく翻訳されていないページは、英語のソースから配信され、英語のテキストであることが示されます。
英語は引き続き信頼できる情報源です。各ロケールページは、対応する英語ページの構造、リンク、コードサンプルを逐語的に反映します。