輕鬆的I18N適用於Next.js +10
下一個插件+ i18n API
筆記
我們正在使用Next-Translate版本3.0.0版。近幾個月來,我們非常專注於Brisa 。因此,自上次發行以來已經很長時間了,但是我們並沒有忘記下一譯。我們正在製作一個新版本,該版本將帶來許多改進和新功能。我們很高興與大家分享。

該庫的主要目的是在下一個js環境中保持翻譯盡可能簡單。
Next-Translate有兩個部分: Next.js插件+ I18N API 。
特徵

在配置文件中,您指定了名稱空間需要的每個頁面:
i18n.json
{
"pages" : {
"*" : [ "common" ] ,
"/" : [ "home" ] ,
"/cart" : [ "cart" ] ,
"/content/[slug]" : [ "content" ] ,
"rgx:^/account" : [ "account" ]
}
// rest of config here...
}在此處閱讀有關如何添加命名空間JSON文件的信息。
Next-Translate可確保每個頁面僅具有當前語言的名稱空間。因此,如果我們有100個地區,則只會加載1個。
為此,我們使用一個WebPack加載程序,該WebPack加載程序在Next.js方法( GetStaticProps , GetServersideProps或GetInitialProps )中加載必要的翻譯文件。如果您的頁面上已經有這些方法之一,則WebPack加載程序將使用您自己的方法,但是它將使用的默認值是:
getStaticProps 。這是大多數頁面上使用的默認方法,除非它是接下來兩個點中指定的頁面。這是用於性能的,因此計算是在構建時間而不是請求時間進行的。getServerSideProps 。這是[slug].js或[...catchall].js等動態頁面的默認方法。這是因為對於這些頁面,有必要定義getStaticPaths ,並且不知道每個語言環境應如何sl。同樣,默認情況下,只有您編寫getstaticpaths,它才會使用GetStaticProps來加載翻譯。getInitialProps 。這是使用HOC的這些頁面的默認方法。這是為了避免衝突,因為HOC可以覆蓋getInitialProps 。整個過程都是透明的,因此在您的頁面中,您可以直接消耗使用useTranslation Hook來使用這些名稱空間,而您無需做任何其他事情。
如果由於某種原因您在_app.js文件中使用getInitialProps ,則翻譯只會從_app.js加載到getInitialProps中。我們建議出於優化原因,除非絕對必要,否則您不使用這種方法。
yarn add next-translatenext-translate-plugin是一種工具,它允許開發人員在構建過程中逐頁有效地處理翻譯。它與next-translate軟件包不同,該軟件包允許開發人員訪問所需的代碼中的翻譯。該插件通過解析所有頁面,搜索翻譯並重寫頁面文件,將翻譯添加到其中。這使該插件成為更有效,更靈活的解決方案,用於處理下一個js應用程序中的翻譯。建議將插件作為DevDectionenty安裝。
yarn add next-translate-plugin -D在您的next.config.js文件中:
const nextTranslate = require ( 'next-translate-plugin' )
module . exports = nextTranslate ( )或者,如果您已經有Next.config.js文件並要保留其更改,請將配置對像傳遞到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的國際化功能。
默認情況下,命名空間以這種方式在/erentes root Directory上指定:
/地區
.
├── ca
│ ├── common.json
│ └── home.json
├── en
│ ├── common.json
│ └── home.json
└── es
├── common.json
└── home.json每個文件名匹配pages配置屬性上指定的名稱空間,而每個文件內容應與此相似:
{
"title" : " Hello world " ,
"variable-example" : " Using a variable {{count}} "
}但是,您可以使用另一個目的地使用LoadLocaleflom配置屬性來保存命名空間文件:
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 ) ,
}然後,使用頁面及其組件中的翻譯:
頁/示例
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 | 默認場所的ISO(默認為“ en”)。 | string | "en" |
locales | 一個帶有所有語言在項目中使用的數組。 | string[] | [] |
loadLocaleFrom | 更改加載命名空間的方式。 | 返回JSON Promise function 。 | 默認情況下,正在加載來自Locales root目錄的命名空間。 |
pages | 定義每個頁面中使用的名稱空間的對象。對象的示例: {"/": ["home", "example"]} 。要在所有頁面中添加名稱空間,您應該使用鍵"*" ,ex: {"*": ["common"]} 。也可以使用rgx:在前面: {"rgx:/form$": ["form"]} 。您還可以使用函數而不是數組來提供一些命名空間,具體取決於某些規則,例如: { "/": ({ 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)中擁有的HOC,請勿使用NOIST-NON-NON-REACTSTATICS,以免包含超過必要的KB (與頁面中的GetInitialProps不同的靜態值很少使用) 。如果您與靜態有任何衝突,則可以在此處添加NOIND-NON-REACT統計(或任何其他選擇)。見一個示例。 | Function | null |
extensionsRgx | 更改WebPack加載程序使用的正則撥號,以查找Next.js頁面。 | Regex | /.(tsx|ts|js|mjs|jsx)$/ |
revalidate | 如果您想在每個頁面上有一個默認的重新驗證,我們會通過傳遞數字重新驗證來為您提供這樣做的機會。您仍然可以在具有不同的重新估計金額的頁面上定義GetStaticProp,並覆蓋此默認值覆蓋。 | Number | 如果您不定義它,默認情況下,頁面將沒有重新估計。 |
pagesInDir | 如果您next ./my-app以更改頁面所在的位置,則可以在這裡定義my-app/pages以便下一個翻譯可以猜測它們在哪裡。 | String | 如果您不定義它,默認情況下,頁面將在pages和src/pages等經典位置中搜索。 |
localesToIgnore | 指出這些地方使用中間件將默認場所前綴(在Next +12中,了解如何做)時,要忽略這些地區。 | Array<string> | ['default'] |
allowEmptyStrings | 更改應如何處理翻譯的空字符串。如果省略或以true的方式傳遞,它將返回一個空字符串。如果以false的方式傳遞,請返回密鑰名稱本身(包括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 Hook。) 。
withTranslation hoc返回一個組件,其中一個名為i18n的額外道具(object {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")類似,您可以使用第二個參數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字符串 - i18n條目的鍵(命名空間:鍵)components - 數組|對象 - 在數組的情況下,每個索引對應於定義的標籤<0> / <1> 。如果對象,每個鍵對應於定義的標籤<example> 。values - 對象 - 查詢參數fallback - 字符串|字符串[] - 可選。後備I18NKEY如果I18NKEY不匹配。defaultTrans字符串 - 鍵的默認翻譯。如果使用後備密鑰,則僅在用盡所有後備後才使用。ns當沒有嵌入i18nKey中時使用的名稱空間returnObjects -boolean-獲得所有翻譯的JSON的一部分。查看更多。如果我們需要Trans組件的功能,但需要一個插值字符串,而不是t(props.i18nKey)函數的輸出,也有一個TransText組件,該組件採用text prop而不是i18nKey 。
text - 字符串 - (選項)包含需要插值的標籤的字符串components - 數組|對象 - 這與Trans完全相同(見上文)。用returnObjects: true映射t()的輸出:true: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 - 字符串[] - 要下載的動態名稱空間列表 -必需。fallback - ReactNode-遞減顯示名稱空間正在加載的後備。 -選修的。dynamic - 函數 - 默認情況下,它使用配置中的LoadLocalelocale flos loadlocaleth in Configuration加載名稱空間,但是您可以指定另一個目標。 -選修的。尺寸:〜1.3kb?
異步函數以加載t函數外部組件 /頁面。它在服務器端和客戶端都可以使用。
與Usetranslation Hook不同,我們可以在此處使用任何名稱空間,它不必是“頁面”配置中定義的名稱空間。它下載了指示為運行時參數的名稱空間。
您可以通過將數組作為參數加載多個名稱空間,在這種情況下,默認名稱空間將是拳頭。
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是下文提供者Next-Translate內部使用的上下文提供商,以提供當前的lang和頁面名稱空間。所以也許您永遠不需要這個。
但是,它暴露於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由Next-Translate內部使用。所以也許您永遠不需要這個。但是,如果您禁用WebPack Loader選項並決定手動加載名稱空間,我們將其公開。
如果您不想使用WebPack加載程序,則應將其放入_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 ,則還應使用LoadNamespaces助手來手動加載每個頁面上的名稱空間。
尺寸:〜1.9kb?
Next-Translate內部使用了loadNamespaces 。所以也許您永遠不需要這個。但是,如果您禁用WebPack Loader選項並決定手動加載名稱空間,我們將其公開。
要加載名稱空間,您必須在頁面中返回助手提供的道具。
import loadNamespaces from 'next-translate/loadNamespaces'
export function getStaticProps ( { locale } ) {
return {
props : {
... ( await loadNamespaces ( { locale , pathname : '/about' } ) ) ,
}
}
}為了好的工作,您的_app.js必須用AppWithi18n包裝。此外,必須將loadLocaleFrom屬性屬性定義。
我們通過將其添加到此後綴的鍵(或在沒有_前綴的密鑰下嵌套)來支持6個複數形式(取自CLDR複數頁面):
_zero_one (單數)_two (雙)_few (paucal)_many (如果有單獨的類,也用於分數)_other (必需 - 一般複數形式 - 如果語言只有單個形式)也使用在此處查看有關複數的更多信息。
只需要最後_other ,因為它是所有語言環境中唯一使用的常見複數形式。
所有其他復數形式都取決於語言環境。例如,英語只有兩個: _one和_other (1貓與2隻貓)。有些語言還有更多,例如俄羅斯和阿拉伯語。
此外,我們還通過指定數字( _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僅適用於現代瀏覽器,如果您想在舊式瀏覽器中使用它,則應添加一個polyfill。
您可以以這種方式定義翻譯中的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配置函數格式化參數。
在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 為了更改當前語言,您可以使用Next.js導航(鏈接和路由器)通過locale環境道具。
使用Next.js的useRouter Hook的一個可能的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 。可以使用next.js userouter鉤訪問locales列表。
您可以將一個名為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提取了所有復雜性。
如果您有興趣了解有關News Next.js 13 App dir範式如何使用New Next-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 Hook或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渲染頁面,其中使用useRouter鉤訪問頁面pages/page-name.js以獲取該locale 。
但是,由於頁面已從pages dir移至app dir ,因此該I18N路由不再正常工作。
在下一個翻譯時,我們選擇不重新實現此功能,因為我們的目標是成為翻譯頁面而不是路由它們的庫。我們希望將來,此功能將在app目錄中實現。
我們建議以下內容:
[lang]添加到第一級。也就是說,您的所有頁面都將在內部/app/[lang] 。i18n.(js|json)文件,以在開始時包含/[lang] 。 module.exports = {
locales: ['en', 'ca', 'es'],
defaultLocale: 'en',
pages: {
'*': ['common'],
- '/': ['home'],
+ '/[lang]': ['home'],
- '/second-page': ['home'],
+ '/[lang]/second-page': ['home'],
},
}在下一個翻譯級別,我們已經根據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-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,頁面位於src/peg folder上,從SRC/Translations加載具有不同結構的srcant。
此演示是在此存儲庫中:
git clone [email protected]:aralroca/next-translate.gitcd next-translateyarn && yarn example:complex與復雜的演示相似,但有了一些額外pages內容:我們將使用新的佈局系統使用Next.js +13 App文件夾。
此演示是在此存儲庫中:
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 謝謝這些好人(表情符號鑰匙):
Aral Roca Gomez ? | Vincent Ducorps | BjörnRave | 賈斯汀 | pol ? | AdemílsonF。 Tonato | 福爾 |
Bickmaev5 | 皮埃爾·格里瑪(Pierre Grimaud) | 羅馬·米奇(Roman Minchyn) | Egor | 達倫 | Giovanni Giordano | 尤金 |
安德魯·鐘 | thanh Minh | 麵包師 | 帕特里克 | 范特羅 | 喬伊 | Gurkerl83 |
TeemuPerämäki | 路易斯·塞拉諾(Luis Serrano) | J-Schumann | 安德烈·霍(Andre Hsu) | SLEVY85 | BerndArtmüller | Rihardsščeredins |
N4N5 | 盧比·莫亞(RubénMoya) | 湯姆·埃斯特雷斯(Tom Esterez) | 丹·尼德姆(Dan Needham) | Bruno Antunes | Kaan Atakan | 羅曼 |
ArnauJiménez | Edwin Veldhuizen | DUC非政府組織越野 | 比勒·赫拉利(Billel Helali) | WUIF | 米歇爾酒吧 | WUIF |
瑪麗斯·恩格爾(Marces Engel) | 米歇爾酒吧 | 拖動 | 瑪麗斯·恩格爾(Marces Engel) | Vasco Silva | Vsevolod Volkov | 菲利克斯·元 |
穆罕默德·齊克里(Muhammad al Ziqri) | 馬塞洛·奧利維拉(Marcelo Oliveira) | 扎克·桑德蘭(Zack Sunderland) | 安德魯烤箱 | 丹妮 | Mateusz Lesiak | curetix |
Honza ? | Hardikbandhiya | 蒂姆·彼得斯 | 李明 | 費爾南多·加西亞·埃爾南德斯(FernandoGarcíaHernández) | Hichem Fantar | Huseyin onal |
傑西·馬丁 |
該項目遵循全企業規範。歡迎任何形式的貢獻!