JSX の翻訳 - 条件分岐の使い方
導入
国際化でよく見かける代表的な間違いのひとつは、 シンプルな三項演算子を複数の翻訳呼び出しに分割してしまうことです。 たとえば次のような形になることがよくあります。
const gt = useGT()
return (
<>
<span>
<T>ダークモード:</T>
</span>
<Button>{enabled ? gt('オン') : gt('オフ')}</Button>
</>
)ほとんどの場合、これは意図どおりに動作します。i18n を実装する前のコードは、おそらく { enabled ? 'On' : 'Off' } のような形だったはずです。
i18n のために gt() 関数を追加したのも、おそらく既存のコード構造の自然な延長として行っただけでしょう。
これを見るたびに、正直少しゾッとします。これはライブラリの想定された使い方とはまったく異なります。 特に機械翻訳を使うという前提では、これが誤りである理由は 2 つあります。(1) コンテキスト と (2) 柔軟性 です。
コンテキスト
意味は単に単語そのものだけでなく、その単語がどのように表示・提示されているかにも含まれています。 「back」という単語は、戻る矢印の上にあれば、カイロプラクターの履歴書に書かれた「back」とはまったく別の意味になる可能性があります。 また、より広い文脈がなければ、翻訳者(人間であっても)はその単語を正しく訳すのが難しい場合があります。 WhatsApp の i18n 部門が、画像編集ツール上の「crop」という単語を、ドイツ語で農業の「crop(作物)」として翻訳してしまったという有名な話があります。
このコンテキストの問題を回避するために、<T> と <Branch> コンポーネントを使ってコンテンツの見せ方に関する情報を渡すことができます。
この例では、それによって「翻訳者」に対し、「on」と「off」が何を意味するのかについて、より大きな全体像を提供できます。
<T>
<span>ダークモード:</span>
<Button>
<Branch branch={enabled.toString()} true="オン" false="オフ" />
</Button>
</T>柔軟性
コンテキスト以外にも、LLM 翻訳を活用できるおもしろいポイントとして、コードの構造を理解できることがあります。 コンポーネントの並び順が言語によって変わる場合の例を見てみましょう。
<T>
<Branch branch={atHome.toString()} true="家" false="職場" />で昼食を食べます。
</T>つまり、次の 2 つの文があるとします:
- 「I eat lunch at home」
- 「I eat lunch at work」
中国語(普通話)では次のようになります:
- 「我在家吃午餐」
- 「我在公司吃午餐」
<T> コンポーネントは、この場合に文の語順を変える必要があることを認識し、
それに合わせて子要素を並べ替えます。これは、文字列翻訳で三項演算子を使うだけでは簡単には実現できません。
<T>
私は
<Branch branch={atHome.toString()} true="家" false="会社" />
で昼食を食べます。
</T>結論
この記事から一つだけでも学びを持ち帰るとしたら、「コードの中でコンテキストと柔軟性を最大限に活用する方法を常に探すべきだ」という点です。
そのための最も手軽なアプローチのひとつが、<Branch /> コンポーネントを使うことです。
詳しくは、<Branch /> コンポーネント のドキュメントを参照してください。