【Nextjs】i18nextを利用して多言語化する

Next.jsで日本語ページ、英語ページ、その他言語ページといったように同一ページで他言語を行います。

Next.jsでは、国際化(i18next)のサポートがデフォルトで行われています。
デフォルトのロケールを指定すると、自動的にルーティングをしてくれます。

今回は、文字列の中にコンポーネントを埋め込みたい(文字の途中を太字にしたい、リンクにしたいなど)ことをしたかったため、ライブラリでreact-i18next を導入することにしました。

本記事では、react-i18nextを使った方法を説明します。

目次

react-i18nextのインストール

react-i18nextはnpmを使ってインストールできます。

$ npm install react-i18next i18next --save

yarn の場合は、yarn add で追加します。

$ yarn add react-i18next i18next

react-i18nextで実装する

多言語ファイル(.json)を作成

今回は、日本語(ja.json)と英語(en.json)を準備します。

{
 "header": {
    "mypage": "マイページ"
  },
}
{
 "header": {
    "mypage": "MyPage"
  },
}

ディレクトリは、下記にします。

|-- project
|-- src
|-- |-- data
|-- |-- |-- text
|-- |-- |-- |-- ja
|-- |-- |-- |-- |-- ja.json
|-- |-- |-- |-- en
|-- |-- |-- |-- |-- en.json
|-- |-- i18n.ts
...

react-i18nextで実装

公式サイトを確認しながら、初期設定をします。

https://react.i18next.com/guides/quick-start#configure-i18next

i18n.tsファイルを作成していきます。

resources として日本語、英語の翻訳ファイルを読み込みます。

import translationJa from "./data/text/ja/ja.json";
import translationEn from "./data/text/en/en.json";

const resources = {
ja: {
    translation: translationJa,
  },
  en: {
    translation: translationEn,
  },
};

インポートしたi18nでinitすることで利用可能になります。

i18n
  .use(initReactI18next)
  .init({
    resources,
    fallbackLng: "ja",
    lng: "ja",
    interpolation: {
      escapeValue: false,
    },
  });

ソース全体

import i18n from "i18next";
import { initReactI18next } from "react-i18next";

import translationJa from "./data/text/ja/ja.json";
import translationEn from "./data/text/en/en.json";

const resources = {
ja: {
    translation: translationJa,
  },
  en: {
    translation: translationEn,
  },
};

i18n
  // pass the i18n instance to react-i18next.
  .use(initReactI18next)
  // init i18next
  // for all options read: https://www.i18next.com/overview/configuration-options
  .init({
    resources,
    fallbackLng: "ja",
    lng: "ja",
    interpolation: {
      escapeValue: false, // not needed for react as it escapes by default
    },
  });

export default i18n;

providerで読み込み

i18n.tsをインポートして、使用するコンポーネントをI18nextProviderで囲みます。
これにより、複数のi18nextインスタンスをサポートすることができ、デフォルトの名前空間を定義することができます。

import i18n from "@/i18n";
import { I18nextProvider } from "react-i18next";

// ...略

<I18nextProvider i18n={i18n} defaultNS={"translation"}>
 <Component {...pageProps} />
</I18nextProvider>

コンポーネントでreact-i18nextを利用して翻訳する

useTranslationを利用して、t関数とi18nインスタンスを取得することができます。
t関数に翻訳ファイルで定義したオブジェクト名を渡すことで翻訳を取得できます。

import { useTranslation } from "react-i18next";

export function MyComponent() {
  const { t, i18n } = useTranslation("translation", { lng: locale });
  return <div>{t("header.mypage")}</div>
}

翻訳ファイルの文字列の一部をコンポーネントで置き換える、and 文字列を挿入する

翻訳ファイルの一部を、太文字にする、リンクにする、などは割と多くの要件があったりします。

これは、<Trans>コンポーネントで実現できます。

翻訳ファイルにテキストを追加

{
 "header": {
    "mypage": "マイページ"
  },
 "news": {
    "title": "<bold>{{name}}</bold>です。"
  },
}

コンポーネントで置き換える。文字列を置き換える

import {Trans} from "react-i18next";

export function MyComponent() {
 const { t, i18n } = useTranslation("translation", { lng: locale });

 return (
  <Trans
         t={t}
         i18nKey={'news.title'}
         values={{ name: 'world'}}
         components={{ bold: <strong /> }}
  ></Trans>
 )
}

Summary

react-i18nextを使うことで簡単に多言語化が実現できます。
基本的には翻訳ファイルに定義をそれぞれ追加していくだけなので、ソース上も管理が楽になります。

よかったらシェアしてね!
目次