next.js +10用の簡単なi18n
次のプラグイン+ I18N API
注記
Next-Translateのバージョン3.0.0を使用しています。ここ数ヶ月で、私たちはブリサに非常に焦点を合わせてきました。そのため、前回のリリースから長い時間が経ちましたが、次の翻訳を忘れていません。多くの改善と新機能をもたらす新しいバージョンに取り組んでいます。皆さんと共有できることを非常に楽しみにしています。

このライブラリの主な目標は、next.js環境で翻訳を可能な限りシンプルに保つことです。
Next-Translateには、 next.jsプラグイン+ i18n APIの2つの部分があります。
特徴

構成ファイルで、名前空間が必要な各ページを指定します。
i18n.json
{
"pages" : {
"*" : [ "common" ] ,
"/" : [ "home" ] ,
"/cart" : [ "cart" ] ,
"/content/[slug]" : [ "content" ] ,
"rgx:^/account" : [ "account" ]
}
// rest of config here...
}名前空間JSONファイルを追加する方法については、こちらをご覧ください。
Next-Translateは、各ページに現在の言語の名前空間のみがあることを保証します。したがって、100個のロケールがある場合、ロードされるのは1つだけです。
これを行うには、next.jsメソッド( GetStaticProps 、 getServersidePropsまたはgetInitialProps )内に必要な変換ファイルをロードするWebパックローダーを使用します。これらのメソッドのいずれかがすでにページにある場合、Webpackローダーは独自のメソッドを使用しますが、使用するデフォルトは次のとおりです。
getStaticProps 。これは、次の2つのポイントで指定されたページでない限り、ほとんどのページで使用されるデフォルトの方法です。これはパフォーマンスのためであるため、計算は要求時間の代わりにビルド時間で行われます。getServerSideProps 。これは[slug].jsまたは[...catchall].jsのような動的ページのデフォルトの方法です。これは、これらのページでは、 getStaticPathsを定義する必要があり、各ロケールのスラグがどのようにあるべきかについての知識がないためです。同様に、デフォルトでは、GetStaticPathsを書くだけで、翻訳をロードするためにGetStaticPropsをすでに使用します。getInitialProps 。これは、HOCを使用するこれらのページのデフォルトメソッドです。これは、HOCがgetInitialPropsを上書きする可能性があるため、競合を回避するためです。このプロセス全体は透明であるため、ページではuseTranslationフックを直接消費して名前空間を使用できます。他に何もする必要はありません。
何らかの理由で_app.jsファイルでgetInitialPropsを使用する場合、翻訳は_app.jsのgetInitialPropsにのみロードされます。最適化の理由で、絶対に必要でない限り、このアプローチを使用しないことをお勧めします。
yarn add next-translatenext-translate-plugin開発者がビルドプロセス中にページごとに翻訳を効率的に処理できるツールです。これは、 next-translateパッケージとは異なるため、開発者は必要なコードの翻訳にアクセスできます。プラグインは、すべてのページを解析し、翻訳を検索し、翻訳を追加するページファイルを書き換えることで機能します。これにより、プラグインは、next.jsアプリケーション内で翻訳を処理するためのより効率的で柔軟なソリューションになります。プラグインを開発者としてインストールすることをお勧めします。
yarn add next-translate-plugin -Dnext.config.jsファイル:
const nextTranslate = require ( 'next-translate-plugin' )
module . exports = nextTranslate ( )または、 next.config.jsファイルが既にあり、その変更を保持したい場合は、configオブジェクトをnextTranslate()に渡します。たとえば、Webpackの場合、次のようにできます。
const nextTranslate = require ( 'next-translate-plugin' )
module . exports = nextTranslate ( {
webpack : ( config , { isServer , webpack } ) => {
return config ;
}
} )プロジェクトのルートに構成ファイルi18n.json (またはmodule.exportsを備えたi18n.js )を追加します。各ページには名前空間が必要です。詳細については、構成セクションをご覧ください。
{
"locales" : [ " en " , " ca " , " es " ],
"defaultLocale" : " en " ,
"pages" : {
"*" : [ " common " ],
"/" : [ " home " , " example " ],
"/about" : [ " about " ]
}
}構成ファイルでは、ここで指定した構成と、next.js 10の国際化に関する独自の機能の両方を使用できます。
デフォルトでは、名前空間は、この方法で/locesルートディレクトリで指定されています。
/ロケール
.
├── ca
│ ├── common.json
│ └── home.json
├── en
│ ├── common.json
│ └── home.json
└── es
├── common.json
└── home.json各ファイル名は、 pages Configプロパティで指定された名前空間と一致しますが、各ファイルコンテンツはこれに似ている必要があります。
{
"title" : " Hello world " ,
"variable-example" : " Using a variable {{count}} "
}ただし、別の宛先を使用して、loadlocalefrom configurationプロパティを使用して名前空間ファイルを保存できます。
i18n.js
{
// ...rest of config
"loadLocaleFrom" : ( lang , ns ) =>
// You can use a dynamic import, fetch, whatever. You should
// return a Promise with the JSON file.
import ( `./myTranslationsFiles/ ${ lang } / ${ ns } .json` ) . then ( ( m ) => m . default ) ,
}次に、ページとそのコンポーネントの翻訳を使用します。
ページ/example.js
import useTranslation from 'next-translate/useTranslation'
export default function ExamplePage ( ) {
const { t , lang } = useTranslation ( 'common' )
const example = t ( 'variable-example' , { count : 42 } )
return < div > { example } </ div > // <div>Using a variable 42</div>
}ページで直接翻訳を使用できます。各ページで名前空間ファイルを手動でロードすることを心配する必要はありません。 Next-Translateプラグインは、ページに必要な名前空間のみが現在の言語でのみロードされます。
構成ファイルでは、ここで指定した構成と、next.js 10の国際化に関する独自の機能の両方を使用できます。
| オプション | 説明 | タイプ | デフォルト |
|---|---|---|---|
defaultLocale | デフォルトのロケール(デフォルトとして "en")のISO。 | string | "en" |
locales | プロジェクトで使用するすべての言語を備えた配列。 | string[] | [] |
loadLocaleFrom | 名前空間のロード方法を変更します。 | JSONでPromiseを返すfunction 。 | デフォルトでは、 Loces Root Directoryから名前空間をロードしています。 |
pages | 各ページで使用される名前空間を定義するオブジェクト。オブジェクトの例: {"/": ["home", "example"]} 。すべてのページに名前空間を追加するには、キー"*" 、ex: {"*": ["common"]}を使用する必要があります。 rgx: on Front: {"rgx:/form$": ["form"]}を使用してRegexを使用することもできます。また、配列の代わりに関数を使用して、いくつかのルールに応じていくつかの名前空間を提供することもできます。例: { "/": ({ req, query }) => query.type === 'example' ? ['example'] : []} | Object<string[] or function> | {} |
logger | 開発と生産で欠落しているキーをログに記録する機能。 i18n.json構成ファイルとして使用している場合は、 i18n.jsに変更する必要があります。 | function | デフォルトでは、ロガーは、開発中のみconsole.warnを実行する関数です。 |
loggerEnvironment | ロガーがブラウザ、ノード、またはその両方で実行されるかどうかを定義する文字列 | "node" | "browser" | "both" | "browser" |
logBuild | 各ページには、名前空間、現在の言語、および名前空間のロードに使用される方法を示すログがあります。これにより、無効にすることができます。 | Boolean | true |
loader | Webpackローダーを無効にし、各ページの名前空間を手動でロードする場合は、このオプションを無効にすることで、その機会を提供します。 | Boolean | true |
interpolation | 補間に使用される区切り文字を変更します。 | {prefix: string; suffix: string, formatter: function } | {prefix: '{{', suffix: '}}'} |
keySeparator | ネストされたキーに使用されるセパレーターを変更します。 falseに設定して、JSON翻訳ファイルにネストされているキーを無効にします。自然なテキストをキーとして使用する場合は、便利です。 | string | false | '.' |
nsSeparator | キーから名前空間を分割するchar。自然なテキストをキーとして使用する場合は、それをfalseに設定する必要があります。 | string | false | ':' |
defaultNS | useTranslationまたは翻訳キーに渡されない場合に使用されるデフォルトの名前空間。 | string | undefined |
staticsHoc | API(appwithi18n)にあるHOCSは、必要以上にKBを含めないようにHoist-Non-reactaticsを使用しないでください(ページのGetInitialPropsとは異なる静的値はめったに使用されません) 。 staticsと競合する場合は、ここにHoist-Non-reactatics(またはその他の代替)を追加できます。例を参照してください。 | Function | null |
extensionsRgx | webpackローダーで使用されているRegexを変更して、next.jsページを見つけます。 | Regex | /.(tsx|ts|js|mjs|jsx)$/ |
revalidate | 各ページにデフォルトの再確認を行いたい場合は、再検証するために番号を渡すことで、そうする機会を与えます。再検証量が異なるページでgetStaticPropsを定義し、このデフォルトのオーバーライドをオーバーライドすることができます。 | Number | 定義しない場合、デフォルトではページに再検証がありません。 |
pagesInDir | next ./my-appを実行してページのある場所を変更すると、ここで次の翻訳がどこにあるかを推測できるように、ここでmy-app/pages定義できます。 | String | 定義しない場合、デフォルトでは、 pagesやsrc/pagesなどの古典的な場所でページが検索されます。 |
localesToIgnore | ミドルウェアを使用してデフォルトのロケールをプレフィックスするときにこれらのロケールを無視するように示します(次の+12で、それを行う方法を学びます) | Array<string> | ['default'] |
allowEmptyStrings | 翻訳された空の文字列を処理する方法を変更します。省略または渡された場合、空の文字列を返します。偽として渡された場合、キー名自体(NSを含む)を返します。 | Boolean | true |
サイズ:〜150b?
このフックは、ページ /コンポーネントで翻訳を使用する推奨方法です。
例:
import React from 'react'
import useTranslation from 'next-translate/useTranslation'
export default function Description ( ) {
const { t , lang } = useTranslation ( 'ns1' ) // default namespace (optional)
const title = t ( 'title' )
const titleFromOtherNamespace = t ( 'ns2:title' )
const description = t `description` // also works as template string
const example = t ( 'ns2:example' , { count : 3 } ) // and with query params
const exampleDefault = t ( 'ns:example' , { count : 3 } , { default : "The count is: {{count}}." } ) // and with default translation
return (
< >
< h1 > { title } </ h1 >
< p > { description } </ p >
< p > { example } </ p >
< >
)
} t関数:
i18nKeyに埋め込まれていない場合に使用する名前空間。 useTranslationと同様ですが、フックではありません。このヘルパーは、 APP dirでのみ機能します。
const { t , lang } = createTranslation ( 'ns1' ) // default namespace (optional)
const title = t ( 'title' )サイズ:〜560b?
これはuseTranslationフックの代替ですが、機能しないこれらのコンポーネントの場合はありません。 (お勧めしませんが、 useTranslationフックを使用する方が良いです。) 。
withTranslation HOCは、 i18n (オブジェクト{t:function、lang:string})という名前の追加のプロップを含むコンポーネントを返します。
例:
import React from 'react'
import withTranslation from 'next-translate/withTranslation'
class Description extends React . Component {
render ( ) {
const { t , lang } = this . props . i18n
const description = t ( 'common:description' )
return < p > { description } </ p >
}
}
export default withTranslation ( NoFunctionalComponent ) useTranslation("common")と同様に、使用するデフォルトの名前空間を定義する2番目のパラメーターでwithTranslationで呼び出すことができます。
export default withTranslation(NoFunctionalComponent, "common")
サイズ:〜1.4kb?
テキスト内でHTMLを使用していくつかの翻訳を行う必要がある場合(太字、リンクなど)、 Transコンポーネントはまさにこれに必要なものです。この場合にのみこのコンポーネントを使用することをお勧めします。他のケースについては、代わりにuseTranslationフックの使用を強くお勧めします。
例:
// The defined dictionary entry is like:
// "example": "<0>The number is <1>{{count}}</1></0>",
< Trans
i18nKey = "common:example"
components = { [ < Component /> , < b className = "red" /> ] }
values = { { count : 42 } }
/>または、 componentsプロップをオブジェクトとして使用します。
// The defined dictionary entry is like:
// "example": "<component>The number is <b>{{count}}</b></component>",
< Trans
i18nKey = "common:example"
components = { {
component : < Component /> ,
b : < b className = "red" /> ,
} }
values = { { count : 42 } }
defaultTrans = "<component>The number is <b>{{count}}</b></component>"
/>i18nKey -string -key of i18n entry(namespace:key)components - 配列|オブジェクト - 配列の場合、各インデックスは定義されたタグ<0> / <1>に対応します。オブジェクトの場合、各キーは定義されたタグ<example>に対応します。values - オブジェクト - クエリパラメーションfallback - 文字列| string [] - オプション。 i18nkeyが一致しない場合、フォールバックi18nkey。defaultTrans -String-キーのデフォルト変換。フォールバックキーを使用すると、すべてのフォールバックを使い果たした後にのみ使用されます。ns i18nKeyに埋め込まれていない場合に使用する名前空間returnObjects -boolean-すべての翻訳でJSONの一部を取得します。もっと参照してください。 Transコンポーネントの機能が必要ですが、 t(props.i18nKey)関数の出力ではなく、文字列を補間する必要がある場合、 i18nKeyの代わりにtextプロップを取るTransTextコンポーネントもあります。
text - 文字列 - (オプションで)補間を必要とするタグを含む文字列components - 配列|オブジェクト - これはTransとまったく同じ動作をします(上記参照)。これは、returnObjectsを使用してt()の出力をマッピングする場合に特に便利ですreturnObjects: true :
// The defined dictionary entry is like:
// "content-list": ["List of <link>things</link>", "with <em>tags</em>"]
const contentList = t ( 'someNamespace:content-list' , { } , { returnObjects : true } ) ;
{ contentList . map ( ( listItem : string ) => (
< TransText
text = { listItem }
components = { {
link : < a href = "some-url" /> ,
em : < em /> ,
} }
/>
) }サイズ:〜1.5kb?
DynamicNamespacesコンポーネントは、たとえばモダルで動的な名前空間をロードするのに役立ちます。
例:
import React from 'react'
import Trans from 'next-translate/Trans'
import DynamicNamespaces from 'next-translate/DynamicNamespaces'
export default function ExampleWithDynamicNamespace ( ) {
return (
< DynamicNamespaces namespaces = { [ 'dynamic' ] } fallback = "Loading..." >
{ /* ALSO IS POSSIBLE TO USE NAMESPACES FROM THE PAGE */ }
< h1 >
< Trans i18nKey = "common:title" />
</ h1 >
{ /* USING DYNAMIC NAMESPACE */ }
< Trans i18nKey = "dynamic:example-of-dynamic-translation" />
</ DynamicNamespaces >
)
} ['dynamic']名前空間をpages構成にリストしないでください。
pages: {
'/my-page' : [ 'common' ] , // only common namespace
}namespaces -String [] - ダウンロードする動的な名前空間のリスト -必須。fallback - ReactNode-フォールバックは、名前空間が読み込まれています。 -オプション。dynamic - 関数 - デフォルトでは、構成内のLoadLocalefromを使用して名前空間をロードしますが、別の宛先を指定できます。 -オプション。サイズ:〜1.3kb?
非同期関数は、コンポーネント /ページ外にt関数をロードします。サーバー側とクライアント側の両方で動作します。
Usetranslationフックとは異なり、ここでは任意の名前空間を使用できます。「ページ」構成で定義されている名前空間である必要はありません。ランタイムのパラメーターとして示されている名前空間をダウンロードします。
アレイをパラメーターとして提供することにより、複数の名前空間をロードできます。この場合、デフォルトの名前空間はFISTのものになります。
Inside getStaticProps例:
import getT from 'next-translate/getT'
// ...
export async function getStaticProps ( { locale } ) {
const t = await getT ( locale , 'common' )
const title = t ( 'title' )
return { props : { title } }
}APIルート内の例:
import getT from 'next-translate/getT'
export default async function handler ( req , res ) {
const t = await getT ( req . query . __nextLocale , 'common' )
const title = t ( 'title' )
res . statusCode = 200
res . setHeader ( 'Content-Type' , 'application/json' )
res . end ( JSON . stringify ( { title } ) )
}複数の名前空間の読み込みの例:
import getT from 'next-translate/getT'
export default async function handler ( req , res ) {
const t = await getT ( req . query . __nextLocale , [ 'common' , 'errors' ] )
const title = t ( 'title' ) // The default namespace is the first one.
const errorMessage = t ( 'errors:app_error' ) // The default namespace is the first one.
res . statusCode = 200
res . setHeader ( 'Content-Type' , 'application/json' )
res . end ( JSON . stringify ( { title } ) )
}サイズ:〜3kb?
I18nProvider 、次の翻訳で内部的に使用されるコンテキストプロバイダーであり、現在のラングとページの名前空間を提供します。だから多分あなたはこれを決して必要としないでしょう。
ただし、APIは場合によっては有用であるため、APIにさらされています。たとえば、ページで多言語翻訳を使用します。
I18nProvider名前空間を蓄積しているため、古いものを維持するために新しい名前の名前を変更できます。
import React from 'react'
import I18nProvider from 'next-translate/I18nProvider'
import useTranslation from 'next-translate/useTranslation'
// Import English common.json
import commonEN from '../../locales/en/common.json'
function PageContent ( ) {
const { t , lang } = useTranslation ( )
console . log ( lang ) // -> current language
return (
< div >
< p > { t ( 'common:example' ) /* Current language */ } </ p >
< p > { t ( 'commonEN:example' ) /* Force English */ } </ p >
</ div >
)
}
export default function Page ( ) {
const { lang } = useTranslation ( )
return (
< I18nProvider lang = { lang } namespaces = { { commonEN } } >
< PageContent />
</ I18nProvider >
)
}サイズ:〜3.7kb?
appWithI18nは、次の翻訳によって内部的に使用されます。だから多分あなたはこれを決して必要としないでしょう。ただし、WebPack Loaderオプションを無効にし、名前空間を手動でロードすることを決定した場合に備えて、APIで公開します。
WebPackローダーを使用したくない場合は、これを_app.jsファイルに配置する必要があります(_app.jsファイルがない場合は_app.jsファイルを作成します)。
例:
_app.js
import appWithI18n from 'next-translate/appWithI18n'
import i18nConfig from '../i18n'
function MyApp ( { Component , pageProps } ) {
return < Component { ... pageProps } />
}
// Wrapping your _app.js
export default appWithI18n ( MyApp , {
... i18nConfig ,
// Set to false if you want to load all the namespaces on _app.js getInitialProps
skipInitialProps : true ,
} ) skipInitialProps=trueの場合は、各ページの名前空間を手動でロードするためにLoadNamesSpacesヘルパーを使用する必要があります。
サイズ:〜1.9kb?
loadNamespaces 、Next-Translateによって内部的に使用されます。だから多分あなたはこれを決して必要としないでしょう。ただし、WebPack Loaderオプションを無効にし、名前空間を手動でロードすることを決定した場合に備えて、APIで公開します。
名前空間をロードするには、ヘルパーが提供する小道具をページに返す必要があります。
import loadNamespaces from 'next-translate/loadNamespaces'
export function getStaticProps ( { locale } ) {
return {
props : {
... ( await loadNamespaces ( { locale , pathname : '/about' } ) ) ,
}
}
}うまく機能するには、 _app.jsがappwithi18nで包まれる必要があります。また、定義するためにloadLocaleFrom configurationプロパティが必須です。
この接尾辞に追加することにより、6つの複数形(CLDR Pluralsページから取得)をサポートします(または_プレフィックスなしでキーの下にネストする):
_zero_one (singular)_two (dual)_few (paucal)_many (分数が別のクラスがある場合にも使用)_other (必須 - 複数形の形式 - 言語に単一のフォームのみがある場合にも使用されます)複数の詳細については、こちらをご覧ください。
すべてのロケールで使用される唯一の一般的な複数形であるため、最後の_otherのみが必要です。
他のすべての複数形はロケールに依存します。たとえば、英語には2 _other _oneロシア語やアラビア語のように、いくつかの言語にはもっと多くの言語があります。
さらに、数( _0 、 _999 )を指定することにより、正確な一致もサポートし、これはすべてのロケールで機能します。これが例です:
コード:
// **Note**: Only works if the name of the variable is {{count}}.
t ( 'cart-message' , { count } )名前空間:
{
"cart-message_0" : "The cart is empty" , // when count === 0
"cart-message_one" : "The cart has only {{count}} product" , // singular
"cart-message_other" : "The cart has {{count}} products" , // plural
"cart-message_999" : "The cart is full" , // when count === 999
}または
{
"cart-message" : {
"0" : "The cart is empty" , // when count === 0
"one" : "The cart has only {{count}} product" , // singular
"other" : "The cart has {{count}} products" , // plural
"999" : "The cart is full" , // when count === 999
}
}Intl.PluralRules APIは、最新のブラウザでのみ使用できます。レガシーブラウザで使用する場合は、ポリフィルを追加する必要があります。
この方法で、翻訳内でHTMLを定義できます。
{
"example-with-html" : " <0>This is an example <1>using HTML</1> inside the translation</0> "
}例:
import Trans from 'next-translate/Trans'
// ...
const Component = ( props ) => < p { ... props } />
// ...
< Trans
i18nKey = "namespace:example-with-html"
components = { [ < Component /> , < b className = "red" /> ] }
/ >レンダリングされた結果:
< p > This is an example < b class =" red " > using HTML </ b > inside the translation </ p > components配列の各インデックスは、定義の<index></index>に対応します。
componentsアレイでは、各要素の子供を渡す必要はありません。子供は計算されます。
名前空間では、このようなネストされたキーを定義することができます。
{
"nested-example" : {
"very-nested" : {
"nested" : " Nested example! "
}
}
}それを使用するには、「」を使用する必要があります。 IDセパレーターとして:
t `namespace:nested-example.very-nested.nested`また、配列として使用することもできます。
{
"array-example" : [
{ "example" : " Example {{count}} " },
{ "another-example" : " Another example {{count}} " }
]
}オプションreturnObjectsを使用してすべての配列翻訳を取得します。
t ( 'namespace:array-example' , { count : 1 } , { returnObjects : true } )
/*
[
{ "example": "Example 1" },
{ "another-example": "Another example 1" }
]
*/また、keyseparatorをキーとして使用してすべての翻訳を取得することも可能です。デフォルトは'.'です。 :
t ( 'namespace:.' , { count : 1 } , { returnObjects : true } )
/*
{
"array-example": [
{ "example": "Example 1" },
{ "another-example": "Another example 1" }
]
}
*/翻訳が存在しない場合は、フォールバック( string|string[] )を定義して他の翻訳を検索できます。
const { t } = useTranslation ( )
const textOrFallback = t (
'ns:text' ,
{ count : 1 } ,
{
fallback : 'ns:fallback' ,
}
)フォールバックのリスト:
const { t } = useTranslation ( )
const textOrFallback = t (
'ns:text' ,
{ count : 42 } ,
{
fallback : [ 'ns:fallback1' , 'ns:fallback2' ] ,
}
)トランスコンポーネント:
< Trans
i18nKey = "ns:example"
components = { [ < Component /> , < b className = "red" /> ] }
values = { { count : 42 } }
fallback = { [ 'ns:fallback1' , 'ns:fallback2' ] } // or string with just 1 fallback
/> interpolation.format config関数を使用してパラメーションをフォーマットできます。
i18n.js :
const formatters = {
es : new Intl . NumberFormat ( "es-ES" ) ,
en : new Intl . NumberFormat ( "en-EN" ) ,
}
return {
// ...
interpolation : {
format : ( value , format , lang ) => {
if ( format === 'number' ) return formatters [ lang ] . format ( value )
return value
}
}
}英語の名前空間:
{
"example" : " The number is {{count, number}} "
}スペイン語の名前空間:
{
"example" : " El número es {{count, number}} "
}使用:
t ( 'example' , { count : 33.5 } )返品:
The number is 33.5El número es 33,5 現在の言語を変更するにはlocale next.jsナビゲーション(リンクとルーター)を使用することができます。
Next.jsのuseRouterフックを使用した可能性のあるChangeLanguageコンポーネントの例:
import React from 'react'
import Link from 'next/link'
import useTranslation from 'next-translate/useTranslation'
import i18nConfig from '../i18n.json'
const { locales } = i18nConfig
export default function ChangeLanguage ( ) {
const { t , lang } = useTranslation ( )
return locales . map ( ( lng ) => {
if ( lng === lang ) return null
return (
< Link href = "/" locale = { lng } key = { lng } >
{ t ( `layout:language-name- ${ lng } ` ) }
</ Link >
)
} )
} setLanguageを使用して、同じページを保持しながら言語を変更することもできます。
import React from 'react'
import setLanguage from 'next-translate/setLanguage'
export default function ChangeLanguage ( ) {
return (
< button onClick = { async ( ) => await setLanguage ( 'en' ) } > EN </ button >
)
} localesリストにアクセスして言語を変更する別の方法はNext.js routerを使用することです。 localesリストには、next.js userouterフックを使用してアクセスできます。
ユーザー定義言語を使用してNEXT_LOCALEという名前のCookieを値として設定できます。これにより、ロケールを強制することができます。
フックの例:
import { useRouter } from 'next/router'
// ...
function usePersistLocaleCookie ( ) {
const { locale , defaultLocale } = useRouter ( )
useEffect ( persistLocaleCookie , [ locale , defaultLocale ] )
function persistLocaleCookie ( ) {
if ( locale !== defaultLocale ) {
const date = new Date ( )
const expireMs = 100 * 24 * 60 * 60 * 1000 // 100 days
date . setTime ( date . getTime ( ) + expireMs )
document . cookie = `NEXT_LOCALE= ${ locale } ;expires= ${ date . toUTCString ( ) } ;path=/`
}
}
} 場合によっては、ページが現在の言語にある場合、別の言語でいくつかのテキストを表示するいくつかの例外を実行することができます。
この場合、 I18nProviderを使用してこれを達成できます。
ここでそれを行う方法を学びましょう。
Next-Translateは、デフォルトでNode.js Process( process.cwd() )の現在の作業ディレクトリを使用します。
変更したい場合は、使用できます。
NEXT_TRANSLATE_PATH環境変数。相対パスと絶対パスの両方をサポートしますprocess.chdir(PATH_TO_NEXT_TRANSLATE)移動するには、 process.cwd()を移動しますサーバーコンポーネントとクライアントコンポーネントに関しては、同じものを異なるページにロードするのが難しい場合があります。このプロセスを簡素化するために、 next-translate-pluginを使用してすべての複雑さを抽出しました。
Next-Translateが新しいnext.13アプリDIRパラダイムでどのように動作するかについて詳しく知りたい場合は、詳細な説明については、この記事をご覧ください。
「ページ」フォルダーの代わりに「アプリ」フォルダーを使用する場合、 next-translate-plugin変更を自動的に検出し、次の翻訳構成に触れる必要はありません。唯一の違いは、「ページ」構成プロパティが「アプリ」フォルダー内にあるページを参照することです。
i18n.js
module . exports = {
locales : [ 'en' , 'ca' , 'es' ] ,
defaultLocale : 'en' ,
pages : {
'*' : [ 'common' ] ,
'/' : [ 'home' ] , // app/page.tsx
'/second-page' : [ 'home' ] , // app/second-page/page.tsx
} ,
} 「ページ」フォルダーを「アプリ」に変更するだけで、 useTranslationフックまたはTransコンポーネントを使用してページ内で翻訳を消費できます。各ページにどの名前空間がロードされているかを知るために、ログ(有効にしている場合)が表示され、他のすべてが同じである必要があります。
?サーバーページ/コンポーネント(+0kb): app/page.js :
import useTranslation from 'next-translate/useTranslation'
export default function HomePage ( ) {
const { t , lang } = useTranslation ( 'home' )
return < h1 > { t ( 'title' ) } </ h1 >
} ?§クライアントページ/コンポーネント(+498b): app/checkout/page.js
"use client"
import useTranslation from 'next-translate/useTranslation'
export default function CheckoutPage ( ) {
const { t , lang } = useTranslation ( 'checkout' )
return < h1 > { t ( 'title' ) } </ h1 >
} next.js 10はi18nルーティングサポートを導入し、 /es/page-nameにナビゲートすることでページをレンダリングすることができます。ここで、ページpages/page-name.jsにuseRouterフックを使用してlocaleを取得します。
ただし、ページはpagesディレクトリからアプリDIRに移動されているため、このI18Nルーティングは正しく機能しなくなりました。
次の翻訳では、ページをルーティングするのではなく、ページを翻訳するライブラリになることを目指しているため、この機能を再実装しないことを選択しました。将来、この機能がapp Directoryに実装されることを願っています。
以下をお勧めします。
[lang]最初のレベルに追加します。つまり、すべてのページは内部/app/[lang]になります。/[lang]を含むようにi18n.(js|json) module.exports = {
locales: ['en', 'ca', 'es'],
defaultLocale: 'en',
pages: {
'*': ['common'],
- '/': ['home'],
+ '/[lang]': ['home'],
- '/second-page': ['home'],
+ '/[lang]/second-page': ['home'],
},
} Next-TranslateレベルではsearchParams.get('lang')およびparams.langに従って、すでに自動的に言語を検出します。そのため、各ページに対して構成する必要はありません。サーバー/クライアントページ/コンポーネント内でnext-translate通常どおり使用できます。
import useTranslation from 'next-translate/useTranslation'
import Trans from 'next-translate/Trans'
export default function Page ( ) {
const { t , lang } = useTranslation ( 'common' )
return (
< >
< h1 > { t `title` } </ h1 >
< Trans i18nKey = "common:another-text" components = { [ < b /> ] } />
</ >
)
} Next.jsリポジトリにnext-translateのデモがあります:
それを使用するには:
npx create-next-app --example with-next-translate with-next-translate-app
# or
yarn create next-app --example with-next-translate with-next-translate-appこのデモはこのリポジトリにあります:
git clone [email protected]:aralroca/next-translate.gitcd next-translateyarn && yarn example:basic基本的なデモと同様ですが、いくつかのエクストラがあります:TypeScript、Webpack 5、MDX、_App.jsが上に_app.js、SRC/Pagesフォルダーにあるページ、SRC/翻訳のロードを異なる構造でロードします。
このデモはこのリポジトリにあります:
git clone [email protected]:aralroca/next-translate.gitcd next-translateyarn && yarn example:complex複雑なデモと同様ですが、 pagesフォルダーの代わりにいくつかの追加のデモと同様に、新しいレイアウトシステムを使用してnext.js +13アプリフォルダーを使用しています。
このデモはこのリポジトリにあります:
git clone [email protected]:aralroca/next-translate.gitcd next-translateyarn && yarn example:with-app-directory基本的な例と同様ですが、i18n.json構成ファイルのWebpackローダーを手動で非アクティブにするページ名前空間をロードする。
この方法で使用することをお勧めしません。ただし、Webpackローダーに慣れていない場合は、誰にもそうする機会があります。
このデモはこのリポジトリにあります:
git clone [email protected]:aralroca/next-translate.gitcd next-translateyarn && yarn example:without-loader これらの素晴らしい人々に感謝します(絵文字キー):
アラル・ロカ・ゴメス ? | ヴィンセント・デュコルプス | BjörnRave | ジャスティン | pol ? | アデミルソンF.トナト | フォール |
bickmaev5 | ピエールグリモー | ローマン・ミンキン | エゴール | ダレン | ジョバンニ・ジョルダーノ | ユージン |
アンドリュー・チョン | タンミン | クルトン | パトリック | ヴァントロイ | ジョーイ | gurkerl83 |
TeemuPerämäki | ルイス・セラーノ | J-Schumann | アンドレ・フスー | SLEVY85 | BerndArtmüller | リハードシェレディン |
N4N5 | ルベンモヤ | トム・エステレス | ダン・ニーダム | ブルーノアンチュン | Kaan Atakan | ロマン |
ArnauJiménez | エドウィン・ベルドゥイゼン | duc ngo viet | ビレル・ヘラリ | wuif | MichałBar | wuif |
Marces Engel | MichałBar | ドラッグします | Marces Engel | バスコシルバ | vSevolod Volkov | フェリックスヤン |
ムハンマド・アル・ジクリ | マルセロ・オリベイラ | ザックサンダーランド | アンドリュー・オーブンズ | ダニ | Mateusz Lesiak | キュレティックス |
ホンザ ? | hardikbandhiya | ティム・O・ピーターズ | li ming | フェルナンド・ガルシア・ヘルナンデス | Hichem Fantar | Huseyin onal |
ジェシー・マーティン |
このプロジェクトは、全委員会の仕様に従います。あらゆる種類の貢献を歓迎します!