5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

(React + TypeScript)i18nextで名前空間の導入

Last updated at Posted at 2020-02-04

(React + TypeScript)UseContextとi18nextを使ってi18n対応してみるの続きみたいな感じです。

i18nextを使ったi18n対応で、コンポーネントごとにファイルを分けたいので名前空間を導入します。

名前空間の導入

App.tsx
import { useTranslation, initReactI18next } from 'react-i18next';
import i18n from 'i18next';
import enCommon from './locales/en/common.json';
import jaCommon from './locales/ja/common.json';
import jaNamespace1 from './locales/ja/namespace1.json';
import enNamespace1 from './locales/en/namespace1.json'

i18n.use(initReactI18next).init({
  debug: true,
  resources: {
    en: { common: enCommon },
    ja: { common: jaCommon },
  },
  lng: 'ja',
  fallbackLng: false, 
  returnEmptyString: false, 
});

// 名前空間の追加
i18n.addResources('ja', 'namespace1', jaNamespace1);
i18n.addResources('en', 'namespace1', enNamespace1);

export const App: FC = () => {
  const { i18n } = useTranslation();

  // ...以下省略
}

初期化時にはcommonという名前空間しかありませんでしたが、addResources('locale名', '名前空間(ファイル名)', importしたファイル)という関数を使って別の名前空間を追加できます。

名前空間の使用

Component.tsx
import { useTranslation } from 'react-i18next';

export const Component = () => {
  const { t } = useTranslation('namespace1');
  return(
     <p>{t('テスト1')}</p>
     <p>{t('テスト2')}</p>
  );
}

useTranslation()の引数に名前空間の名前をいれることで、このコンポーネント内ではデフォルトの名前空間として、namespace1.json内で定義されてる単語、文章を出力します。(この例ではテスト1とテスト2がキーになります)

辞書ファイルの自動生成

こちらの記事で紹介されている自動で辞書を生成するbabel-plugin-i18next-extractというライブラリですが、名前空間を自動で検出してくれます(助かるー)。
上記の章のテスト1、テスト2というキーが存在しない場合、自動でテスト1、テスト2というキーを作成してくれます。

package.json
"scripts": {
    "i18next-extract": "NODE_ENV=development babel './src/**/*.{js,jsx,ts,tsx}'"
  },
  "babel": {
    "presets": [
      "react-app"
    ],
    "plugins": [
      [
        "i18next-extract",
        {
          "locales": [
            "ja",
            "en"
          ],
          "outputPath": "./src/locales/{{locale}}/{{ns}}.json"
        }
      ]
    ]
  },
  "dependencies": {
   ...以下省略

ここでoutputPathが出力するjsonファイルになります。
そのため日本語の辞書は、src/locales/ja/namespace1.jsonへ、英語の辞書はsrc/locales/en/namespace1.jsonへ自動的に出力されます。

あとは、yarn i18next-extractするだけです。

疑問

本当は名前空間を導入して、各ページごとに読み込むファイルを分けたかったんですが、うまくいきませんでした。。。
ページごとにi18nを初期化すればできそうだけど、なんか違う様な。。。
詳しい方いらっしゃたら教えてください。

(2020.02.5追記)
一晩寝かせておいたらなんかできました。

ChildComponent.tsx
  useEffect(() => {
    i18n.addResources('ja', 'namespace2', jaNamespace2); 
    i18n.addResources('en', 'namespace2', enNamespace2); 
  },[])

こんな感じでuseEffectで囲うだけ。

参考文献

https://www.i18next.com/overview/api#addresourcebundle
https://i18next-extract.netlify.com/#/configuration

5
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?