🌏
Next.js を next-i18next で i18n 対応させる手順
Next.js を next-i18next で i18n 対応させる手順をまとめます。
最終的なコードは GitHub 参照
0. 事前準備
Next.js でアプリを作成し、必要に応じて TypeScript の設定をおこないます。
1. next-i18next のインストール
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