多言語サイトの踏み抜き記録:UI言語と記事言語は別物
今回サイトに多言語対応を追加するとき、最初はFooterに言語切替を置いて、AIに記事を翻訳させるだけで十分だと思っていた。実際にやってみると、問題は思ったより多かった。
一番の核心はこれ:UI言語、テーマ設定の言語、記事本文の言語は、同じ概念に混ぜてはいけない。
- UI言語:ナビ、Footer、ボタン、日付などのUI文言。
- テーマ設定の言語:Heroの説明、一言、Footerの「About / More / Contact」などのテーマ項目。
- 記事言語:ある記事に実際に存在する本文のバージョン。
日本語のUIしかないのに、記事に日本語訳がなければ、それを日本語記事に偽装することはできないし、リンクをそのまま404にすることもできない。
今回起きた問題
最初は、言語切替で言語がそのままURLに入っていた。例えば /ja/posts/... のように。でも、ある記事に必ずしも日本語版があるわけではないので、すごくちぐはぐな体験になっていた:
- ユーザーが日本語UIに切り替える;
- 中国語しかない記事をクリックする;
- ページが日本語ルートに入る;
- 日本語コンテンツが見つからず、結局404になる。
もう一つの問題は、システムが記事内容を自動で英語と判定していたこと。そうすると、公開や通知の遷移で英語パスに入ってしまう。しかもバックエンドで英語だけを翻訳対象に設定していた場合、英語の原文はもう中国語に翻訳されないので、中国語サイトにも見られるバージョンがなくなる。
繁体字中国語も典型的な問題を露呈した:zh-TW が誤って zh に正規化されていた。ただの言語コードの細部に見えるが、結果としてテーマ設定、記事クエリ、API検証に影響した:
theme/yohaku.zh-TWは確かに存在する;- なのに集約APIは
theme/yohaku.zhを探しに行く; - Footerが簡体字中国語にフォールバックする;
- 後でフロントエンドが
zh-TWに遷移できても、APIが2文字の言語コードしか許可しないためリクエストを拒否する。
今のところ採用している方法
サイトは5つのUI言語を保持している:
zh
zh-TW
en
ja
koバックエンドのAI翻訳の対象言語もこの5つに設定している。
でも、すべての記事で5つのコピーを生成するわけではなく、こうしている:
例えば:
| 原文言語 | 自動生成される翻訳 |
|---|---|
簡体字中国語 zh | 繁体字、英語、日本語、韓国語 |
英語 en | 簡体字、繁体字、日本語、韓国語 |
繁体字 zh-TW | 簡体字、英語、日本語、韓国語 |
こうすれば原文を重複翻訳せずに済むし、どのサイト言語にも実際のコンテンツ版が保証されて、切り替え後に404が出るのを防げる。
原文言語は作者が宣言する
もうシステムに本文から言語を自動推測させない。
今は記事エディタに「コンテンツ言語 / 原文言語」フィールドを置くべきだ。作者が公開時に実際の原文言語を選ぶ。特に選ばなければデフォルトで簡体字中国語にする。
これは重要。原文言語が影響するから:
- 自動翻訳でどの言語を除外するか;
- 翻訳タスクのコンテンツハッシュ;
- 記事を後で更新したときにどの翻訳を再生成するか;
- 通知、遷移、コンテンツの利用可否の判定。
AIは翻訳プロセスで言語を観察できるが、作者が宣言した原文言語をこっそり上書きしてはいけない。
テーマ設定も言語ごとに上書きする
簡体字中国語のテーマ設定を基本設定にすればいい。他の言語は翻訳が必要な項目だけを管理する。例えば:
色、レイアウト、フォントなどのビジュアル設定をコピーする必要はない。そうすれば、後でテーマのスタイルを変更するときは基本設定だけを直せばいい。
繁体字中国語は統一されたcanonical codeを使う必要がある:
ある場所では zh-TW と書き、別の場所では zh に畳んではいけない。そうしないと、テーマの上書き、記事翻訳、APIクエリがそれぞれ違う答えになる。
それでも注意が必要な境界
自動生成の多言語翻訳の前提は、翻訳タスクが最終的に成功すること。
ある言語の翻訳が失敗したら、バックエンドのタスクセンターで見えてリトライできるようにするのがいい。フロントエンドで静かに空ページが出るのは避けたい。すでにある古い記事については、設定完了後に手動で全量翻訳タスクを発火できる。その後は記事の更新保存時に、システムが増分で期限切れや欠落した翻訳を補完する。
今回の一番の収穫はこれ:多言語はURLにプレフィックスを付けることでも、単純な翻訳ボタンでもない。
明確な契約が必要だ:
コンテンツ、UI、テーマの3層が同じ正規化された言語コードを使っていれば、多言語体験は切り替え時に突然途切れたりしない。
多言語翻訳の落とし穴