🌏
Next.js を next-i18next で i18n 対応させる手順
Next.js を next-i18next で i18n 対応させる手順をまとめます。
最終的なコードは GitHub 参照
0. 事前準備
Next.js でアプリを作成し、必要に応じて TypeScript の設定をおこないます。
next-i18next
のインストール
1. yarn add next-i18next
2. 翻訳ファイルの作成
public/static/locales/[locale]
フォルダを作成し、翻訳ファイル(JSON 形式)を格納します。
.
└── public
└── static
└── locales
├── en
| └── common.json
└── de
└── common.json
翻訳ファイルの例:
common.json
{
"hello": "Hello from English!",
"nested": {
"greeting": "How are you, {{name}}?"
}
}
- オブジェクトでネストできます
-
{{ }}
で動的な値が使えます
3. アプリのセットアップ
i18n.js
ルート層に i18n.js
を追加します。
i18n.js
const NextI18Next = require('next-i18next').default;
const { localeSubpaths } = require('next/config').default().publicRuntimeConfig;
const path = require('path');
module.exports = new NextI18Next({
otherLanguages: ['de'],
localeSubpaths,
localePath: path.resolve('./public/static/locales'),
});
(公式 README よりコピペ)
next.config.js
ルート層に next.config.js
を追加します。
next.config
const { nextI18NextRewrites } = require('next-i18next/rewrites');
const localeSubpaths = {};
module.exports = {
rewrites: async () => nextI18NextRewrites(localeSubpaths),
publicRuntimeConfig: {
localeSubpaths,
},
};
(公式 examples/simple/next.config.js
よりコピペ)
_app.tsx
_app.tsx
コンポーネントを HOC appWithTranslation
でラップします。以下のコードは、言語切り替えボタンを含んでいます。
_app.tsx
import type { AppProps } from 'next/app';
import { useEffect, useState } from 'react';
import { appWithTranslation, useTranslation } from '../i18n';
const MyApp = ({ Component, pageProps }: AppProps) => {
const { i18n } = useTranslation();
const [currentLanguage, setCurrentLanguage] = useState(i18n.language || 'en');
useEffect(() => {
i18n.changeLanguage(currentLanguage);
}, [currentLanguage]);
return (
<>
<button
onClick={() => {
setCurrentLanguage('en');
}}
>
EN
</button>{' '}
<button
onClick={() => {
setCurrentLanguage('de');
}}
>
DE
</button>
<Component {...pageProps} />
</>
);
};
export default appWithTranslation(MyApp);
- HOC
appWithTranslation
でラップします -
i18n.changeLanguage(currentLanguage)
言語設定を切り替えれます
index.tsx
ページレベルのコンポーネントを HOC withTranslation
でラップします。
index.tsx
import { NextPage } from 'next';
import { withTranslation } from '../i18n';
import { TFunction } from 'next-i18next';
interface HomeProps {
readonly t: TFunction;
}
const Home: NextPage<HomeProps> = ({ t }) => {
return (
<div>
<h2>{t('hello')}</h2>
<p>{t('nested.greeting', { name: 'Kei' })}</p>
</div>
);
};
export default withTranslation('common')(Home);
- HOC
withTranslation
でラップします -
t()
で翻訳テキストを呼びます -
t()
の第2引数に動的な値(オブジェクト)を渡せます
必要な設定は以上です。
Discussion