Легкий i18n для следующего.js +10
Следующий плагин + i18n API
Примечание
Мы работаем с версией 3.0.0 Next-Translate. В последние месяцы мы были очень сосредоточены на Брисе . Так что прошло много времени с момента последнего релиза, но мы не забыли о следующем трансляте. Мы работаем над новой версией, которая принесет много улучшений и новых функций. Мы очень рады поделиться этим со всеми вами.

Основная цель этой библиотеки - сохранить переводы максимально простыми в среде Next.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 -nampaces.
Next-Translate гарантирует, что на каждой странице есть свои пространства имен только с текущим языком. Так что, если у нас будет 100 локалов, будет загружен только 1.
Для этого мы используем загрузчик WebPack , который загружает необходимые файлы перевода в методы следующих.js ( GetStaticProps , GetServersIdeProps или GetInitialProps ). Если у вас уже есть один из этих методов на вашей странице, WebPack Loader будет использовать ваш собственный метод, но по умолчанию, которые он будет использовать:
getStaticProps . Это метод по умолчанию, используемый на большинстве страниц , если это не страница, указанная в следующих двух точках. Это для производительности, поэтому расчеты выполняются во время сборки вместо времени запроса.getServerSideProps . Это метод по умолчанию для динамических страниц , таких как [slug].js или [...catchall].js . Это связано с тем, что для этих страниц необходимо определить getStaticPaths , и нет никакого знания о том, как должны быть слизняки для каждой локали. Точно так же, как это по умолчанию, только то, что вы пишете GetStaticPaths, тогда он уже будет использовать GetStaticProps для загрузки переводов.getInitialProps . Это метод по умолчанию для этих страниц, которые используют HOC . Это во избежание конфликтов, потому что HOC может перезаписать getInitialProps . Весь этот процесс прозрачен , поэтому на ваших страницах вы можете напрямую потреблять крюк useTranslation , чтобы использовать пространства имен, и вам не нужно ничего делать.
Если по какой -то причине вы используете getInitialProps в вашем файле _app.js , то переводы будут загружены только в ваши getInitialProps от _app.js . Мы рекомендуем, чтобы по оптимизации вы не используете этот подход, если это не абсолютно необходимо.
yarn add next-translate next-translate-plugin -это инструмент, который позволяет разработчикам эффективно обрабатывать переводы на странице за страницей в процессе сборки. Он отличается от пакета next-translate , который позволяет разработчикам получить доступ к переводам в коде, где это необходимо. Плагин работает, анализируя все страницы, поиск переводов и переписывая файл страницы, добавляя в него переводы. Это делает плагин более эффективным и гибким решением для обработки переводов в приложении Next.js. Рекомендуется установить плагин в качестве DevDependency.
yarn add next-translate-plugin -DВ вашем файле следующего.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 (или i18n.js с module.exports ) в корне проекта. Каждая страница должна иметь свои пространства имен. Посмотрите на это в разделе конфигурации для получения более подробной информации.
{
"locales" : [ " en " , " ca " , " es " ],
"defaultLocale" : " en " ,
"pages" : {
"*" : [ " common " ],
"/" : [ " home " , " example " ],
"/about" : [ " about " ]
}
}В файле конфигурации вы можете использовать как конфигурацию, которую мы указали здесь, так и собственные функции о интернационализации Next.js 10.
По умолчанию пространства имен указаны в каталоге /локальных корневых.
/локации
.
├── 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}} "
}Тем не менее, вы можете использовать еще один пункт назначения для сохранения файлов пространств имен, используя свойство настройки LoadLocalefform:
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 ) ,
}Затем используйте переводы на странице и ее компоненты:
Страницы/Пример.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.js 10.
| Вариант | Описание | Тип | По умолчанию |
|---|---|---|---|
defaultLocale | ISO локали по умолчанию («en» в качестве по умолчанию). | string | "en" |
locales | Массив со всеми языками для использования в проекте. | string[] | [] |
loadLocaleFrom | Измените способ загрузки пространств имен. | function , которая возвращает Promise с JSON . | По умолчанию загружает пространства имен из корневого каталога локалов . |
pages | Объект, который определяет пространства имен, используемые на каждой странице. Пример объекта: {"/": ["home", "example"]} . Чтобы добавить пространства имен на все страницы, вы должны использовать ключ "*" , Ex: {"*": ["common"]} . Также возможно использовать Regex с помощью 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 | Чар, чтобы разделить пространство имен от ключа. Вы должны установить его на false , если вы хотите использовать натуральный текст в качестве ключей. | string | false | ':' |
defaultNS | Пространство имен по умолчанию используется, если не передано в useTranslation или в ключе перевода. | string | undefined |
staticsHoc | HOCS, которые мы имеем в нашем API (Appwithi18n), не используют Staist-Non-React-Statics, чтобы не включать больше Kb, чем необходимо (статические значения, отличные от GetInitialProps на страницах, редко используются) . Если у вас есть какое-либо конфликт со статикой, вы можете добавить здесь статику поднятия (или любую другую альтернативу). См. Пример. | Function | null |
extensionsRgx | Измените резервуар, используемую WebPack Loader, чтобы найти страницы 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 , но не будучи крючком. Этот помощник работает только в приложении .
const { t , lang } = createTranslation ( 'ns1' ) // default namespace (optional)
const title = t ( 'title' )Размер : ~ 560b?
Это альтернатива useTranslation Hook, но в HOC для этих компонентов, которые не являются функциональными. (Не рекомендуется, лучше использовать крюк useTranslation .) .
HOC withTranslation возвращает компонент с дополнительной опорой именованной 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,4 КБ?
Иногда нам нужно сделать некоторые переводы с 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 - Ключ из записи i18n (пространство имен: ключ)components - массив | Объект - В случае массива каждый индекс соответствует определенной теге <0> / <1> . В случае объекта каждая клавиша соответствует определенной теге <example> .values - объект - параметры запросаfallback - строка | string [] - необязательно. Запасная сторона i18nkey, если i18nkey не совпадает.defaultTrans - String - перевод по умолчанию для ключа. Если используются запасные клавиши, они будут использоваться только после исчерпания всех запасных.ns - пространство имен для использования, когда ни один не встроен в i18nKeyreturnObjects - Boolean - Получите часть JSON со всеми переводами. Увидеть больше. В тех случаях, когда нам требуется функциональность Trans -компонента, но нуждается в интерполировании строки , а не вывода функции t(props.i18nKey) , существует также компонент TransText , который принимает text опору вместо i18nKey .
text - строка - строка, которая (необязательно) содержит теги, требующие интерполяцииcomponents - массив | Объект - это ведет себя точно так же, как Trans (см. Выше). Это особенно полезно при сопоставлении вывода 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,5 КБ?
Компонент 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 - function - по умолчанию. Он использует LoadLocaleFrom в конфигурации для загрузки пространств имен, но вы можете указать другое место назначения. - Необязательный .Размер : ~ 1,3 КБ?
Асинхронная функция для загрузки функции t / страниц наружных компонентов. Он работает как на стороне сервера, так и на стороне клиента.
В отличие от крючка usetranslation, мы можем использовать здесь любое пространство имен, это не должно быть пространство имен, определенное в конфигурации «страницы». Он загружает пространство имен, указанное как параметр во время выполнения.
Вы можете загрузить несколько пространств имен, предоставив массив в качестве параметра, в данном случае пространство имен по умолчанию будет кулаком.
Пример внутри 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,7 КБ?
appWithI18n внутренне используется следующим транслятом. Так что, может быть, вам это никогда не понадобится . Тем не менее, мы выставляем его в API, если вы отключите опцию 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,9 КБ?
loadNamespaces внутри используются в следующем трансляте. Так что, может быть, вам это никогда не понадобится . Тем не менее, мы выставляем его в API, если вы отключите опцию 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.plurulrules API доступен только для современных браузеров , если вы хотите использовать его в Legacy Browsers, вы должны добавить полифилл.
Вы можете определить 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! "
}
}
}Чтобы использовать его, вы должны использовать «». в качестве идентификационного сепаратора:
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" }
]
*/ Кроме того, можно получить все переводы, используя ключевой фары в качестве ключа, по умолчанию есть '.' :
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 Чтобы изменить текущий язык, вы можете использовать locale навигацию.
Пример возможного компонента ChangeLanguage с использованием крючка useRouter от Next.js :
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 можно получить с помощью Hook lecome.js userouter.
Вы можете установить файл cookie с именем NEXT_LOCALE с пользовательским языком в качестве значения, таким образом, локаль может быть вынужден.
Пример крюка:
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 .
Узнайте, как это сделать здесь.
Следующий транслат использует по умолчанию текущий рабочий каталог процесса Node.js ( process.cwd() ).
Если вы хотите его изменить, вы можете использовать:
NEXT_TRANSLATE_PATH . Он поддерживает как относительный, так и абсолютный путьprocess.chdir(PATH_TO_NEXT_TRANSLATE) для перемещения process.cwd() Когда дело доходит до компонентов сервера и клиентских компонентов, может быть сложно загрузить одно и то же на разных страницах. Чтобы упростить этот процесс, мы извлекли всю сложность, используя next-translate-plugin .
Если вы заинтересованы в том, чтобы узнать больше о том, как Next-Translate работает с новой парадигмой приложений Next.js 13, ознакомьтесь с этой статьей для подробного объяснения.
Если вы используете папку «Приложение» вместо папки «Страницы», 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 Hook для получения locale .
Однако, поскольку страницы были перемещены со pages DIR в DIR APP , эта маршрутизация 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/Pages, загружают локалы из SRC/переводов с другой структурой.
Эта демонстрация в этом репозитории:
git clone [email protected]:aralroca/next-translate.gitcd next-translateyarn && yarn example:complex Подобно сложной демонстрации, но с некоторой дополнительной: вместо папки pages мы используем папку приложений hearl.js +13 с новой системой макетов.
Эта демонстрация в этом репозитории:
git clone [email protected]:aralroca/next-translate.gitcd next-translateyarn && yarn example:with-app-directoryАналогично, чем основной пример, но загрузка пространств имен страниц вручную деактивирует загрузчик WebPack в файле конфигурации i18n.json.
Мы не рекомендуем его использовать таким образом. Однако мы даем возможность кому -либо сделать это, если им не удобно с нашим погрузчиком WebPack.
Эта демонстрация в этом репозитории:
git clone [email protected]:aralroca/next-translate.gitcd next-translateyarn && yarn example:without-loader Спасибо этим замечательным людям (ключ эмодзи):
Арал Рока Гомес ? | Винсент Дукорпс | Бьорн Рейв | Джастин | Поли ? | Адемилсон Ф. Тонато | Дефект |
Bickmaev5 | Пьер Гримо | Роман Минчин | Egor | Даррен | Джованни Джордано | Юджин |
Эндрю Чунг | Тхан Мин | Груз | Патрик | Вантри | Джои | Gurkerl83 |
Teemu Perämäki | Луис Серрано | J-Schumann | Андре Хсу | Slevy85 | Бернд Артмюллер | Рихардс Шекерны |
N4N5 | Рубен Мойя | Том Эстерез | Дэн Нидхэм | Бруно Антунес | Каан Атакан | Роман |
Арнау Джименес | Эдвин Велдхуйзен | Герцовая НПО Вьетна | Билль Хелали | Вуиф | Михал Бар | Вуиф |
Marces Engel | Михал Бар | Перетаскивать | Marces Engel | Васко Сильва | Vsevolod Volkov | Феликс Ян |
Мухаммед Аль Зикри | Марсело Оливейра | Зак Сандерленд | Эндрю печи | Дани | Матеуш Лесьяк | CURETIX |
Хонза ? | Hardikbandhiya | Тим О. Петерс | Ли Мин | Фернандо Гарсия Эрнандес | Хихем Фантар | Huseyin Onal |
Джесси Мартин |
Этот проект следует за спецификацией всех контролей. Взносы любого вида приветствуются!