Next.js アプリを翻訳する最も簡単な方法(ページ設定あり) 。
実稼働環境で next-i18next (ページ ディレクトリ) を使用していて、スーパーパワーを解放したい場合は、このブログ投稿を参照してください。
アプリ ディレクトリで Next.js 13/14 を使用している場合、next-i18next は必要ありません。このブログ投稿で説明されているように、i18next と React-i18next を直接使用できます。
Next.js は国際化されたルーティングを直接提供しますが、翻訳コンテンツの管理や実際の翻訳機能自体は処理しません。 Next.js が行うことは、ロケールと URL の同期を維持することだけです。
これを補完するために、 next-i18next
、SSG/SSR、複数の名前空間、コード分割などを完全にサポートしながら、残りの機能 (翻訳コンテンツの管理、および React コンポーネントを翻訳するためのコンポーネント/フック) を提供します。
next-i18next
内部で i18next と React-i18next を使用しますが、 next-i18next
のユーザーは翻訳コンテンツを JSON ファイルとして含めるだけでよく、他にはあまり心配する必要はありません。
ライブデモはここから入手できます。このデモ アプリは単純な例であり、それ以上でもそれ以下でもありません。
セットアップも使いやすさも簡単: セットアップに必要な手順は数ステップだけで、構成も簡単です。
その他の要件はありません: next-i18next
追加の依存関係を持たずに Next.js アプリの国際化を簡素化します。
プロダクション対応: next-i18next
SSG/SSR サポートを備えた props として、翻訳と構成オプションをページに渡すことをサポートしています。
next-i18next.config.js
ファイルは、 next-i18next
の構成を提供します。構成後、 appWithTranslation
使用すると、フックを介してコンポーネントでt
(翻訳) 関数を使用できるようになります。
次に、ページレベルのコンポーネントの getStaticProps または getServerSideProps (状況に応じて) にserverSideTranslation
を追加します。
これで、Next.js アプリが完全に翻訳可能になりました。
yarn add next-i18next react-i18next i18next
react
とnext
もインストールする必要があります。
デフォルトでは、 next-i18next
翻訳が次のように編成されることを期待します。
.
└── public
└── locales
├── en
| └── common.json
└── de
└── common.json
この構造は、簡単な例でも見ることができます。
カスタムの方法で翻訳/名前空間を構造化したい場合は、変更したlocalePath
およびlocaleStructure
値を初期化構成に渡す必要があります。
まず、プロジェクトのルートにnext-i18next.config.js
ファイルを作成します。ネストされたi18n
オブジェクトの構文は Next.js から直接取得されます。
これにより、 defaultLocale
とその他のロケールがnext-i18next
に通知され、サーバーに翻訳をプリロードできるようになります。
next-i18next.config.js
/** @type {import('next-i18next').UserConfig} */
module . exports = {
i18n : {
defaultLocale : 'en' ,
locales : [ 'en' , 'de' ] ,
} ,
}
次に、 i18n
オブジェクトをnext.config.js
ファイルに渡して、 next.config.js
ファイルを作成または変更し、ローカライズされた URL ルーティングを有効にします。
next.config.js
const { i18n } = require ( './next-i18next.config' )
module . exports = {
i18n ,
}
next-i18next
がエクスポートする関数は 3 つあり、プロジェクトを翻訳するために使用する必要があります。
これは、 _app
ラップする HOC です。
import { appWithTranslation } from 'next-i18next'
const MyApp = ( { Component , pageProps } ) => (
< Component { ... pageProps } / >
)
export default appWithTranslation ( MyApp )
appWithTranslation
HOC は主にI18nextProvider
追加する役割を果たします。
これは、 getStaticProps
またはgetServerSideProps
(ユースケースに応じて) を介してページレベルのコンポーネントに含める必要がある非同期関数です。
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
export async function getStaticProps ( { locale } ) {
return {
props : {
... ( await serverSideTranslations ( locale , [
'common' ,
'footer' ,
] ) ) ,
// Will be passed to the page component as props
} ,
}
}
serverSideTranslations
next-i18next/serverSideTranslations
からインポートする必要があることに注意してください。これは、NodeJs 固有のコードを含む別のモジュールです。
また、 serverSideTranslations
サーバー環境でのみ実行できるため、 getInitialProps
と互換性がないことに注意してください。一方、 getInitialProps
ページ間を移動するときにクライアント側で呼び出されます。
serverSideTranslations
HOC は主に、翻訳と構成オプションを小道具としてページに渡す役割を果たします。翻訳のあるページにはそれを追加する必要があります。
これは、翻訳自体を行うために実際に使用するフックです。 useTranslation
フックはreact-i18next
から取得されますが、 next-i18next
から直接インポートする必要があります。
react-i18next
のuseTranslation
エクスポートは使用しないでください。 next-i18next
のエクスポートのみを使用してください。
import { useTranslation } from 'next-i18next'
export const Footer = ( ) => {
const { t } = useTranslation ( 'footer' )
return (
< footer >
< p > { t ( 'description' ) } < / p >
< / footer >
)
}
デフォルトでは、 next-i18next
最初のリクエストごとにすべての名前空間をクライアントに送信します。これはコンテンツが少ない小規模なアプリには適切なアプローチですが、多くのアプリではルートに基づいて名前空間を分割することでメリットが得られます。
これを行うには、各ページに必要な名前空間の配列をserverSideTranslations
に渡すことができます。このアプローチは、examples/simple/pages/index.tsx で確認できます。必要な名前空間の空の配列を渡すと、名前空間は送信されません。
注: useTranslation
それを使用するコンポーネントに名前空間を提供します。ただし、 serverSideTranslations
、使用可能な名前空間の合計を React ツリー全体に提供し、ページ レベルに属します。どちらも必須です。
デフォルトでは、 next-i18next
各リクエストでアクティブなロケールのみをクライアントに送信します。これは、クライアントに送信される初期ペイロードのサイズを削減するのに役立ちます。ただし、場合によっては、実行時に他の言語への翻訳も必要になることがあります。たとえば、 useTranslation
フックの getFixedT を使用する場合です。
動作を変更して追加のロケールをロードするには、 serverSideTranslations
の最後の引数としてロケールの配列を渡すだけです。
import { serverSideTranslations } from 'next-i18next/serverSideTranslations';
export async function getStaticProps({ locale }) {
return {
props: {
- ...(await serverSideTranslations(locale, ['common', 'footer'])),
+ ...(await serverSideTranslations(locale, ['common', 'footer'], null, ['en', 'no'])),
},
};
}
その結果、現在の言語に関係なく、 no
ロケールとen
ロケールの両方の翻訳が常にロードされます。
注:
getFixedT
関数を使用するすべてのページに追加の引数を追加する必要があります。
デフォルトでは、 next-i18next
defaultLocale
フォールバックとして追加します。これを変更するには、 fallbackLng
設定します。 i18next
でサポートされるすべての値 ( string
、 array
、 object
、 function
) はnext-i18next
でもサポートされます。
さらに、 nonExplicitSupportedLngs
true
に設定すると、言語のすべてのバリアントをサポートできます。言語ごとに JSON ファイルを提供する必要はありません。 next.js
内でルーティングを有効にするには、すべてのバリアントをlocales
に含める必要があることに注意してください。
注:
fallbackLng
とnonExplicitSupportedLngs
は同時に使用できます。例外が 1 つだけあります。nonExplicitSupportedLngs
がtrue
の場合、fallbackLng
の関数は使用できません。
module . exports = {
i18n : {
defaultLocale : 'en' ,
locales : [ 'en' , 'fr' , 'de-AT' , 'de-DE' , 'de-CH' ] ,
} ,
fallbackLng : {
default : [ 'en' ] ,
'de-CH' : [ 'fr' ] ,
} ,
nonExplicitSupportedLngs : true ,
// de, fr and en will be loaded as fallback languages for de-CH
}
fallbackLng
とnonExplicitSupportedLngs
を使用すると、ページの初期サイズが簡単に大きくなる可能性があることに注意してください。
参考: fallbackLng
をfalse
に設定すると、フォールバック言語 (通常はdefaultLocale
) がシリアル化されません。これにより、最初のページ読み込みのサイズが減少します。
より高度な構成オプションを変更する必要がある場合は、 next-i18next.config.js
経由でそれらを渡すことができます。例えば:
module . exports = {
i18n : {
defaultLocale : 'en' ,
locales : [ 'en' , 'de' ] ,
} ,
localePath :
typeof window === 'undefined'
? require ( 'path' ) . resolve ( './my-custom/path' )
: '/public/my-custom/path' ,
ns : [ 'common' ] ,
}
一部のi18next
プラグイン ( config.use
に渡すことができます) には、関数やその他の JavaScript プリミティブが含まれているため、シリアル化できません。
ユースケースがより高度な場合、これに遭遇する可能性があります。 Next.js が次のようなエラーをスローすることがわかります。
Error: Error serializing `._nextI18Next.userConfig.use[0].process` returned from `getStaticProps` in "/my-page".
Reason: `function` cannot be serialized as JSON. Please only return JSON serializable data types.
これを修正するには、 config.serializeConfig
false
に設定し、構成をappWithTranslation
に手動で渡す必要があります。
import { appWithTranslation } from 'next-i18next'
import nextI18NextConfig from '../next-i18next.config.js'
const MyApp = ( { Component , pageProps } ) => (
< Component { ... pageProps } / >
)
export default appWithTranslation ( MyApp , nextI18NextConfig )
import { serverSideTranslations } from 'next-i18next/serverSideTranslations'
import nextI18NextConfig from '../next-i18next.config.js'
export const getStaticProps = async ( { locale } ) => ( {
props : {
... ( await serverSideTranslations (
locale ,
[ 'common' , 'footer' ] ,
nextI18NextConfig
) ) ,
} ,
} )
getStaticPaths
およびfallback: true
またはfallback: 'blocking'
を使用してサーバー側で生成されたページを使用する場合、上記のデフォルト設定により、ロードのたびにアプリがアンマウントされ、再マウントされ、毎回useEffect(() => {...}, [])
呼び出すなど、さまざまな悪影響が生じます。 useEffect(() => {...}, [])
2 回フックされ、パフォーマンスがわずかに低下します。
これは、これらのページに対して、Next.js が空のserverSideProps
を使用して最初のレンダリングを実行し、次にnext-i18next
変換を含むserverSideProps
を使用して 2 番目のレンダリングを実行するためです。デフォルトの設定では、 serverSideProps
がempty
場合、 i18n
インスタンスは最初はundefined
であり、アンマウントと再マウントが発生します。
この問題を軽減するには、次のことを実行できます。
import { UserConfig } from 'next-i18next' ;
import nextI18NextConfig from '../next-i18next.config.js'
const emptyInitialI18NextConfig : UserConfig = {
i18n : {
defaultLocale : nextI18NextConfig . i18n . defaultLocale ,
locales : nextI18NextConfig . i18n . locales ,
} ,
} ;
const MyApp = ( { Component , pageProps } ) => (
< Component { ... pageProps } / >
)
export default appWithTranslation ( MyApp , emptyInitialI18NextConfig ) // Makes sure the initial i18n instance is not undefined
これは、フォールバック ページの状態でクライアント側のコードが翻訳を表示しようとしない限り機能します。そうしないと、Next.js から「サーバーとクライアントの不一致」エラーが発生します (つまり、サーバーの HTML には実際の翻訳が含まれていますが、クライアントの HTML には同じ場所に翻訳キーがあります)。
これは正常で問題ありません。とにかく、ユーザーに翻訳キーを表示すべきではありません。
v11.0.0 以降、next-i18next はクライアント側での翻訳の読み込みのサポートも提供します。
ユースケースによっては、 serverSideTranslations
を使用せずに、翻訳ファイルを動的にロードしたい場合があります。これは、ページの速度を低下させたくない遅延読み込みコンポーネントの場合に特に便利です。
詳細については、こちらをご覧ください。
リソースはサーバーの起動時に一度読み込まれるため、開発中の翻訳 JSON ファイルに加えられた変更は、サーバーが再起動されるまで読み込まれません。
運用環境では、これは問題になる傾向はありませんが、開発環境では、毎回開発サーバーを再起動せずに、翻訳 JSON ファイルの更新を確認したい場合があります。これを行うには、 reloadOnPrerender
構成オプションをtrue
に設定します。
このオプションは、 serverSideTranslations
が ( getStaticProps
またはgetServerSideProps
で) 呼び出されるたびに翻訳を再ロードします。 getServerSideProps
でserverSideTranslations
使用している場合は、サーバー呼び出しごとにリソースがリロードされるのを避けるために、運用環境ではreloadOnPrerender
無効にすることをお勧めします。
鍵 | デフォルト値 | 注記 |
---|---|---|
defaultNS | 'common' | |
localePath | './public/locales' | 関数にすることもできます。以下の注を参照してください。 (ここのように、構成経由でリソース オプションを直接渡す場合は、null にすることもできます) |
localeExtension | 'json' | localePath が関数の場合は無視されます。 |
localeStructure | '{{lng}}/{{ns}}' | localePath が関数の場合は無視されます。 |
reloadOnPrerender | false | |
serializeConfig | true | |
use (プラグイン用) | [] | |
onPreInitI18next | undefined | ie (i18n) => i18n.on('failedLoading', handleFailedLoading) |
関数としてのlocalePath
は、 (locale: string, namespace: string, missing: boolean) => string
という形式で、ファイル名と拡張子を含むパス全体を返します。 missing
が true の場合は、 i18next-fs-backend
のaddPath
オプションのパスを返し、 false の場合は、 loadPath
オプションのパスを返します。詳細については、 i18next-fs-backend
リポジトリを参照してください。
localePath が関数の場合は、サーバー側で名前空間をプリロードできないため、必ず ns オプションも定義してください。
他のすべての i18next オプションと React-i18next オプションも同様に渡すことができます。
localePath
null
に設定することと組み合わせて、 resources
を直接渡すこともできます。
デフォルトでは、i18next は補間のプレフィックスとして{{
を使用し、サフィックスとして}}
使用します。これらの補間設定をオーバーライドしたい場合、またはオーバーライドする必要がある場合は、カスタム プレフィックスとサフィックスに一致する代替のlocaleStructure
設定も指定する必要があります。
たとえば、 {
と}
を使用する場合、構成は次のようになります。
{
i18n : {
defaultLocale : 'en' ,
locales : [ 'en' , 'nl' ] ,
} ,
interpolation : {
prefix : '{' ,
suffix : '}' ,
} ,
localeStructure : '{lng}/{ns}' ,
}
next-i18next.config.js
パスデフォルトの構成パスを変更する場合は、環境変数I18NEXT_DEFAULT_CONFIG_PATH
を設定できます。
たとえば、 .env
ファイル内で静的パスを設定できます。
I18NEXT_DEFAULT_CONFIG_PATH=/path/to/project/apps/my-app/next-i18next.config.js
または、動的パスのトリックを使用して、 next.config.js
内に以下を設定することもできます。
process . env . I18NEXT_DEFAULT_CONFIG_PATH = ` ${ __dirname } /next-i18next.config.js` ;
// ... Some other imports
const { i18n } = require ( './next-i18next.config' ) ;
// ... Some other code
module . exports = {
i18n ,
...
} ;
これは、i18n 構成ファイルがnext.config.js
と同じディレクトリに存在し、現在の作業ディレクトリがどこにあるかは関係ないことを意味します。これは、たとえば、monorepo があり、プロジェクト ルートからアプリケーションを開始するが、アプリケーションがapps/{appName}
にある場合にnx
で役立ちます。
注意構成next-i18next.config.js
がnext.config.js
と同じディレクトリにない場合は、手動で (またはカスタム スクリプトによって) コピーする必要があります。
プロジェクトに next-i18next を段階的に追加することを計画している場合は、問題を避けるためにnext-i18next.config
をappWithTranslation
に渡すことをお勧めします。
つまり
import nextI18nextConfig from '../../next-i18next.config' ;
//...
export default appWithTranslation ( MyApp , nextI18nextConfig ) ;
詳細については、問題 #2259 を参照してください。
一部のサーバーレス PaaS では、翻訳のパスを見つけることができず、追加の構成が必要になる場合があります。 serverSideTranslations
の使用時にファイルシステムの問題が発生した場合は、 path.resolve
を使用するようにconfig.localePath
を設定します。例はここにあります。
Docker デプロイメントの場合、Next.js ドキュメントのDockerfile
を使用する場合は、 next.config.js
とnext-i18next.config.js
Docker イメージにコピーすることを忘れないように注意してください。
COPY --from=builder /app/next.config.js ./next.config.js
COPY --from=builder /app/next-i18next.config.js ./next-i18next.config.js
組み込みの i18next-fs-backend とは異なる i18next バックエンドを使用することを選択した場合は、 t
関数を呼び出す前に変換リソースがロードされていることを確認する必要があります。 React サスペンスは SSR ではまだサポートされていないため、これは 2 つの異なる方法で解決できます。
1) 名前空間をプリロードします。
この例のように、 ns
オプションを設定します。これを行うと、初期化時にすべての翻訳リソースが確実にロードされます。
2) 準備完了フラグを確認します。
ns
配列を提供できない、または提供したくない場合は、 t
関数を呼び出すと、名前空間がオンザフライでロードされます。これは、 ready === true
またはprops.tReady === true
チェックして「準備ができていない」状態を処理する必要があることを意味します。そうしないと、翻訳がロードされる前にレンダリングされることになり、翻訳が実際に存在する (まだロードされていない) にもかかわらず、「save missing」が呼び出されます。これは、useTranslation フックまたは withTranslation HOC を使用して実行できます。
next export
を実行して静的 HTML エクスポートを生成しようとしているのに、このエラーが発生していますか?
エラー: i18n サポートは次回のエクスポートと互換性がありません。デプロイの詳細については、こちらを参照してください: https://nextjs.org/docs/deployment
ただし、次の言語検出機能を使用してこれを回避する方法があります。このブログ投稿とこのサンプル プロジェクトを確認してください。
子コンポーネントで t 関数を使用するには、複数の方法があります。
t
関数を props 経由で子に渡します。useTranslation
関数を使用します。next-i18next/examples/simple/components/Footer.tsx
e6b5085の6行目
withTranslation
関数を使用するまた、一般に、serverSideTranslations にツリー内で必要なすべての名前空間が含まれていることを常に確認する必要があります。
これらの素晴らしい人々に感謝します (絵文字キー):
ロブ・カペリーニ | アレクサンダー・カチカエフ ? ? | マティアス・ウォッベ ? | ルーカス・フェリシアーノ ? ? | ライアン・レオン | ネイサン・フリーメル ? | アイザック・ヒンマン ️️️️♿️ ? ? ? ? ? ? ? ? ? ? ? ?? ? ? ? ? ? ?️ ? |
アドリアーノ・ライアーノ ️️️️♿️ ? ? ? ? ? ? ? ? ? ? ? ?? ? ? ? ? ? ?️ ? | フェリックス・モシェフ ? | セバスチャン・ヴァンベルセム ? ? |
このプロジェクトは、全員参加者の仕様に従っています。あらゆる種類の貢献を歓迎します!
サービスとしてのローカリゼーション - locize.com
翻訳管理が必要ですか? InContext Editor を使用して翻訳を編集したいですか? i18next の管理者によって提供されたオリジナルを使用してください。
locize を使用すると、i18next と next-i18next の将来を直接サポートできます。