React + @shopify/react-i18nで、翻訳の中で変数展開を行う

Reactでi18n対応をするために @shopify/react-i18n を使うことがあります。
https://github.com/Shopify/quilt/blob/main/packages/react-i18n/README.md

そんな中、翻訳の中で変数展開をしたくなったため、調べたときのメモを残します。

 
目次

 

環境

  • React 18.2.0
  • @shopify/react-i18n 7.8.0
  • @tanstack/react-router 0.0.1-beta.194

なお、 @tanstack/react-router はルーティングのために使用しています。
TanStack Router | React Router, Solid Router, Svelte Router, Vue Router

 

単純な翻訳対応をする

@shopify/react-i18n のドキュメントに従い、i18n対応をしてみます。

まずは、Reactで createRoot するときにProviderを設定します。

const locale = 'ja'
const i18nManager = new I18nManager({
  locale
})


ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <I18nContext.Provider value={i18nManager}>
      <RouterProvider router={router} />
    </I18nContext.Provider>
  </React.StrictMode>
)

 
次に、i18n対応をしたいコンポーネントにて、以下のような翻訳定義を作ります。

const ja = {
  Replacement: {
    withoutReplacement: '単なる翻訳',
  }
}

 
続いて、カスタムフック useI18n を使って設定を行います。

const [i18n] = useI18n({
  id: 'NotFound',
  fallback: ja,
  translations(_) {
    return ja
  },
})

 
後はコンポーネントにて、 i18n.translate を使います。

<p>{i18n.translate('Replacement.withoutReplacement')}</p>

 
この結果、翻訳定義が画面に表示されます。

 

翻訳の中で変数展開する

次に、翻訳の中で変数展開をします。ドキュメントは以下です。
https://github.com/Shopify/quilt/blob/main/packages/react-i18n/README.md#replacements

今回は、翻訳の中に表示した時刻を埋め込んでみます。

 
まずは翻訳定義を追加します。

今回は myArgs という部分に変数展開したいとします。

const ja = {
  Replacement: {
    withoutReplacement: '単なる翻訳',
    withReplacement: '表示日時: {myArgs}'  // 追加
  }
}

 
続いて、 i18n.translate にて上記の翻訳定義を使用します。

この際、第2引数に、翻訳定義で使用したキー (今回の場合 myArgs) を含むオブジェクトを渡します。

// 現在時刻データを用意
const padZero = (value: number) => value.toString().padStart(2, "0")
const current = new Date()
const currentDateTime = [current.getHours(), current.getMinutes(), current.getSeconds()].map((v) => padZero(v)).join(':')

return (
  <>
    <p>{i18n.translate('Replacement.withoutReplacement')}</p>

    {/* 以下を追加 */}
    <p>{i18n.translate('Replacement.withReplacement', {myArgs: currentDateTime})}</p>
  </>
  )

 
再度画面を表示すると、変数展開されて翻訳表示されています。

 

ソースコード

Githubに上げました。
https://github.com/thinkAmi-sandbox/shopify_react_i18n_examples

今回のプルリクはこちら。
https://github.com/thinkAmi-sandbox/shopify_react_i18n_examples/pull/1