next-i18nextの多言語化の設定と日本語をルートにするまで

人生初の多言語化にチャレンジしたWebアプリを開発中です。

next-i18next は i18next と react-i18next を使ってNextJSに使いやすいようにカスタマイズされたライブラリです。

設定がラクで良いのですが <a href="https://github.com/isaachinman/next-i18next">next-i18nextリポジトリのREADME</a> を参考にしてみたもののpathのルートが hoge.com/ja といったようにスラッシュの後にjaがついてしまったのでそれを回避する方法も含めて next-18next の設定を解説。

以下の手順の細かいところはREADMEの方を参考にしてもらえればと。

## next-i18next の設定手順
①ディレクトリを用意する
②configファイルを用意する
③_app.tsxでnext-i18nextをラップしてexportする
④useTranslationで翻訳対象テキストを追加する
⑤getStaticPropsでserverSideTranslationsを設定する


## ①ディレクトリを用意する
react-i18next と違いpublic以下にlocalesフォルダを用意。

```
.
└── public
    └── locales
        ├── en
        |   └── common.json
        └── de
        |   └── common.json
        └── ja
            └── common.json
```

```common.json
ja
{
 "hello": "ハローワールド!"
}

en
{
 "hello": "Hello World!"
}

de
{
 "hello": "Guten Tag, Welt!"
}
```
適当に翻訳JSONにプロパティを追加

## ②configファイルを用意する
next-i18next.config.jsファイル を作成。

これを以下のように設定してnext.config.jsファイル へ読み込んであげます。

```next-i18next.config.js
module.exports = {
  i18n: {
    defaultLocale: 'ja',
    locales: ['en', 'de', 'ja'],
  },
  domains: [
    {
      domain: 'localhost:3000/en',
      defaultLocale: 'en',
      http: true,
    },
    {
      domain: 'localhost:3000/de',
      defaultLocale: 'de',
      http: true,
    },
    {
      domain: 'localhost:3000',
      defaultLocale: 'ja',
      http: true,
    },
  ],
};
```
ここでポイントとして domainsプロパティ の domainプロパティ に言語ごとにルートディレクトリを設定してあげます。

今回はルートディレクトリを日本語にしたかったので defaultLocale: 'ja' のルートを domain: 'localhost:3000' にしました。

next-i18nextのREADMEにはないくだりですが NextJS の <a herf="https://nextjs.org/docs/advanced-features/i18n-routing">Internationalized Routing</a> を参考にしました。

```next.config.js
const { i18n } = require('./next-i18next.config');

module.exports = {
  i18n,
};
```
next.config.js へ next-i18next.config を引っ張ってきます。

## ③_app.tsxでnext-i18nextをラップしてexportする

```_app.tsx
import { appWithTranslation } from 'next-i18next';

const MyApp = ({ Component, pageProps }) => <Component {...pageProps} />;

export default appWithTranslation(MyApp);
```
ここはそのままREADMEの引用ですが export default appWithTranslation(MyApp); でラップしてあげています。

## ④useTranslationで翻訳対象テキストを追加する


```index.tsx
import { VFC } from 'react'
import { useTranslation } from 'next-i18next';
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'

const Home: VFC = () => {
const { t } = useTranslation('common');

  return (
    <>
      <div>{t("hello")}</div>
    </>
  );
}

export async function getStaticProps({ locale }: {locale: string}) {
  return {
    props: {
      ...await serverSideTranslations(locale, ['common']),
    }
  };
}

export default Home;
```
上記のように適当に設定します。 getStaticProps に関しては次に解説。

## ⑤getStaticPropsでserverSideTranslationsを設定する

先の index.tsx に ...await serverSideTranslations(locale, ['common']) を設定しました。

```index.tsx
export async function getStaticProps({ locale }: {locale: string}) {
  return {
    props: {
      ...await serverSideTranslations(locale, ['common']),
    }
  };
}
```

locale には en や ja といった言語のStringの引数が渡されています。
next-i18next.config.js で設定した domainsプロパティ のルート（domain）に応じて locale が渡されます。

ここで、 common.json 以外の辞書を引っ張ってきたいなら ...await serverSideTranslations(locale, ['common', 'header', 'footer']) といったように調整すればできます。