Easy i18n para o próximo.js +10
Próximo plug -in + I18n API
Observação
Estamos trabalhando com a versão 3.0.0 do próximo translato. Nos últimos meses, estamos muito focados em Brisa . Por isso, já faz muito tempo desde o último lançamento, mas não esquecemos o próximo translato. Estamos trabalhando em uma nova versão que trará muitas melhorias e novos recursos. Estamos muito animados para compartilhar com todos vocês.

O principal objetivo desta biblioteca é manter as traduções o mais simples possível em um ambiente Next.js.
O próximo translato tem duas partes: Next.js Plugin + I18N API .
Características

No arquivo de configuração, você especifica cada página que os namespaces precisam:
i18n.json
{
"pages" : {
"*" : [ "common" ] ,
"/" : [ "home" ] ,
"/cart" : [ "cart" ] ,
"/content/[slug]" : [ "content" ] ,
"rgx:^/account" : [ "account" ]
}
// rest of config here...
}Leia aqui sobre como adicionar os arquivos JSON de namespaces.
O Next Translate garante que cada página tenha apenas seus espaços para nome com o idioma atual. Portanto, se tivermos 100 locais, apenas 1 será carregado.
Para fazer isso , usamos um carregador webpack que carrega os arquivos de tradução necessários dentro dos métodos a seguir. Se você já possui um desses métodos em sua página, o carregador Webpack usará seu próprio método, mas os padrões que usarão são:
getStaticProps . Esse é o método padrão usado na maioria das páginas , a menos que seja uma página especificada nos próximos dois pontos. Isso é para desempenho, portanto os cálculos são feitos no tempo de construção, em vez do tempo de solicitação.getServerSideProps . Este é o método padrão para páginas dinâmicas como [slug].js ou [...catchall].js . Isso ocorre porque, para essas páginas, é necessário definir o getStaticPaths e não há conhecimento de como as lesmas devem ser para cada local. Da mesma forma, como é por padrão, apenas que você escreve o GetStaticPats, já usará o GetStaticProps para carregar as traduções.getInitialProps . Este é o método padrão para essas páginas que usam um hoc . Isso é para evitar conflitos porque o Hoc pode substituir um getInitialProps . Todo esse processo é transparente ; portanto, em suas páginas, você pode consumir diretamente o gancho de useTranslation para usar os namespaces e não precisa fazer mais nada.
Se, por algum motivo, você usar um getInitialProps no seu arquivo _app.js , as traduções serão carregadas apenas no seu getInitialProps de _app.js . Recomendamos que, por motivos de otimização, você não use essa abordagem, a menos que seja absolutamente necessário.
yarn add next-translate A next-translate-plugin é uma ferramenta que permite que os desenvolvedores lidem com traduções com eficiência de uma base página a página durante o processo de construção. É distinto do next-translate , que permite aos desenvolvedores acessar as traduções no código onde é necessário. O plug -in funciona analisando todas as páginas, pesquisando as traduções e reescrevendo o arquivo de página adicionando as traduções a ele. Isso torna o plugin uma solução mais eficiente e flexível para lidar com traduções dentro de um aplicativo Next.js. Recomenda -se instalar o plug -in como uma dependência.
yarn add next-translate-plugin -DNo seu arquivo next.config.js :
const nextTranslate = require ( 'next-translate-plugin' )
module . exports = nextTranslate ( ) Ou se você já possui arquivo next.config.js e deseja manter as alterações nele, passe o objeto de configuração para o nextTranslate() . Por exemplo, para Webpack, você pode fazer assim:
const nextTranslate = require ( 'next-translate-plugin' )
module . exports = nextTranslate ( {
webpack : ( config , { isServer , webpack } ) => {
return config ;
}
} ) Adicione um arquivo de configuração i18n.json (ou i18n.js com module.exports ) na raiz do projeto. Cada página deve ter seus espaços nomes. Dê uma olhada na seção de configuração para obter mais detalhes.
{
"locales" : [ " en " , " ca " , " es " ],
"defaultLocale" : " en " ,
"pages" : {
"*" : [ " common " ],
"/" : [ " home " , " example " ],
"/about" : [ " about " ]
}
}No arquivo de configuração, você pode usar a configuração que especificamos aqui e os próprios recursos sobre a internacionalização do Next.js 10.
Por padrão, os namespaces são especificados no diretório raiz /locales dessa maneira:
/Locais
.
├── ca
│ ├── common.json
│ └── home.json
├── en
│ ├── common.json
│ └── home.json
└── es
├── common.json
└── home.json Cada nome do arquivo corresponde ao espaço para nome especificado na propriedade Config pages , enquanto cada conteúdo de arquivo deve ser semelhante a isso:
{
"title" : " Hello world " ,
"variable-example" : " Using a variable {{count}} "
}No entanto, você pode usar outro destino para salvar seus arquivos de namespaces usando o loadlocale de propriedade de configuração:
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 ) ,
}Em seguida, use as traduções na página e seus componentes:
páginas/exemplo.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>
}Você pode consumir as traduções diretamente em suas páginas, não precisa se preocupar em carregar os arquivos de namespaces manualmente em cada página. O próximo plug-in de translate carrega apenas os espaços para nome que a página precisa e somente com o idioma atual.
No arquivo de configuração, você pode usar a configuração que especificamos aqui e os próprios recursos sobre a internacionalização do Next.js 10.
| Opção | Descrição | Tipo | Padrão |
|---|---|---|---|
defaultLocale | ISO da localidade padrão ("EN" como padrão). | string | "en" |
locales | Uma matriz com todos os idiomas a serem usados no projeto. | string[] | [] |
loadLocaleFrom | Altere a maneira como você carrega os espaços para nome. | function que retorna uma Promise com o JSON . | Por padrão, está carregando os espaços para nome do diretório raiz locales . |
pages | Um objeto que define os espaços para nome usados em cada página. Exemplo de objeto: {"/": ["home", "example"]} . Para adicionar namespaces a todas as páginas, você deve usar a chave "*" , ex: {"*": ["common"]} . Também é possível usar regex usando rgx: na frente: {"rgx:/form$": ["form"]} . Você também pode usar uma função em vez de uma matriz, para fornecer alguns espaços para nome, dependendo de algumas regras, ex: { "/": ({ req, query }) => query.type === 'example' ? ['example'] : []} | Object<string[] or function> | {} |
logger | Função para registrar as chaves ausentes no desenvolvimento e produção. Se você estiver usando i18n.json como arquivo de configuração, altere -o para i18n.js | function | Por padrão, o Logger é uma função que faz um console.warn apenas no desenvolvimento. |
loggerEnvironment | String para definir se o madeireiro deve ser executado no navegador, no nó ou em ambos | "node" | "browser" | "both" | "browser" |
logBuild | Cada página possui um log indicando: namespaces, idioma atual e método usado para carregar os namespaces. Com isso, você pode desativá -lo. | Boolean | true |
loader | Se você deseja desativar o carregador webpack e carregar manualmente os espaços para names em cada página, oferecemos a você a oportunidade de fazê -lo desativando essa opção. | Boolean | true |
interpolation | Altere o delimitador usado para interpolação. | {prefix: string; suffix: string, formatter: function } | {prefix: '{{', suffix: '}}'} |
keySeparator | Altere o separador usado para chaves aninhadas. Defina como false para desativar as teclas Nestar nos arquivos de tradução JSON. Pode ser útil se você quiser usar o texto natural como chaves. | string | false | '.' |
nsSeparator | Char para dividir o espaço para nome da chave. Você deve configurá -lo como false se quiser usar o texto natural como chaves. | string | false | ':' |
defaultNS | Namespace padrão usado se não for passado para useTranslation ou na chave de tradução. | string | undefined |
staticsHoc | Os hocs que temos em nossa API (appwithi18n), não usam estatísticas Hoist-Non-react para não incluir mais KB do que o necessário (os valores estáticos diferentes do getinitialProps nas páginas raramente são usados) . Se você tiver algum conflito com a estática, poderá adicionar estatísticas eleistes-não-reagt (ou qualquer outra alternativa) aqui. Veja um exemplo. | Function | null |
extensionsRgx | Altere o regex usado pelo carregador webpack para encontrar as páginas Next.js. | Regex | /.(tsx|ts|js|mjs|jsx)$/ |
revalidate | Se você deseja ter um revalidador padrão em cada página, oferecemos a você a oportunidade de fazê -lo, passando um número para revalidar. Você ainda pode definir o GetStaticProps em uma página com uma quantidade de revalidato diferente e substituir essa substituição padrão. | Number | Se você não definir, por padrão, as páginas não terão revalidador. |
pagesInDir | Se você correr next ./my-app para alterar onde estão suas páginas, poderá definir aqui my-app/pages para que o Next Translate possa adivinhar onde eles estão. | String | Se você não definir, por padrão, as páginas serão pesquisadas nos lugares clássicos como pages e src/pages . |
localesToIgnore | Indique esses locais para ignorar quando você estiver prefixando o local padrão usando um middleware (no próximo +12, aprenda a fazê -lo) | Array<string> | ['default'] |
allowEmptyStrings | Altere a forma como as seqüências vazias traduzidas devem ser tratadas. Se omitido ou passado como verdadeiro, ele retorna uma corda vazia. Se aprovado como falso, retorna o próprio nome (incluindo ns). | Boolean | true |
Tamanho : ~ 150b?
Este gancho é a maneira recomendada de usar traduções em suas páginas / componentes.
Exemplo:
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 >
< >
)
} A função t :
i18nKey . Semelhante à useTranslation , mas sem ser um gancho. Este ajudante funciona apenas no App Dir .
const { t , lang } = createTranslation ( 'ns1' ) // default namespace (optional)
const title = t ( 'title' )Tamanho : ~ 560b?
É uma alternativa ao gancho useTranslation , mas em um hoc para esses componentes que não são funcionais. (Não recomendado, é melhor usar o gancho useTranslation .) .
O hoc withTranslation retorna um componente com um suporte extra chamado i18n (objeto {t: function, lang: string}).
Exemplo:
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 ) Semelhante à useTranslation("common") você pode chamar withTranslation com o segundo parâmetro que define um espaço para nome padrão para usar:
export default withTranslation(NoFunctionalComponent, "common")
Tamanho : ~ 1,4kb?
Às vezes, precisamos fazer algumas traduções com HTML dentro do texto (negrito, links etc.), o componente Trans é exatamente o que você precisa para isso. Recomendamos usar esse componente apenas neste caso, para outros casos, recomendamos o uso do gancho useTranslation .
Exemplo:
// 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 } }
/> Ou usando o suporte components como objeto:
// 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 - chave da entrada i18n (espaço para nome: chave)components - Array | Objeto - No caso de matriz, cada índice corresponde à tag definida <0> / <1> . No caso de objeto, cada tecla corresponde à tag definida <example> .values - Objeto - Params de consultafallback - String | String [] - Opcional. Fallback I18NKEY Se o i18nkey não corresponder.defaultTrans - String - Tradução padrão para a chave. Se as chaves de fallback forem usadas, elas serão usadas somente após esgotar todos os fallbacks.ns - Namespace para usar quando nenhum está incorporado no i18nKeyreturnObjects - Boolean - Obtenha parte do JSON com todas as traduções. Veja mais. Nos casos em que exigimos a funcionalidade do componente Trans , mas precisamos de uma string para ser interpolada, em vez da saída da função t(props.i18nKey) , também existe um componente TransText , que leva um suporte text em vez de i18nKey .
text - String - A sequência que (opcionalmente) contém tags que requerem interpolaçãocomponents - Array | Objeto - isso se comporta exatamente o mesmo que Trans (veja acima). Isso é especialmente útil ao mapear a saída de um t() com 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 /> ,
} }
/>
) }Tamanho : ~ 1,5kb?
O componente DynamicNamespaces é útil para carregar namespaces dinâmicos, por exemplo, em modais.
Exemplo:
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 >
)
} Lembre -se de que o namespace ['dynamic'] não deve ser listado na configuração pages :
pages: {
'/my-page' : [ 'common' ] , // only common namespace
}namespaces - String [] - Lista de namespaces dinâmicos para download - Necessário .fallback - ReactNode - Fallback para exibir enquanto os espaços para nome estão carregando. - opcional .dynamic - por padrão, ele usa o loadlocale de na configuração para carregar os namespaces, mas você pode especificar outro destino. - opcional .Tamanho : ~ 1,3kb?
Função assíncrona para carregar a função t externa componentes / páginas. Funciona no lado do servidor e no lado do cliente.
Ao contrário do gancho USETranslation, podemos usar aqui qualquer espaço para nome, ele não precisa ser um espaço para nome definido na configuração "Páginas". Ele baixa o espaço para nome indicado como um parâmetro no tempo de execução.
Você pode carregar vários namespaces, dando uma matriz como parâmetro; nesse caso, o espaço para nome padrão será o punho.
Exemplo 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 } }
}Exemplo dentro da rota da 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 } ) )
}Exemplo de carregar vários namespaces:
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 } ) )
}Tamanho : ~ 3KB?
O I18nProvider é um provedor de contexto usado internamente pelo Next Translate para fornecer o Lang atual e os espaços para nome da página. Então, talvez você nunca precise disso .
No entanto, é exposto à API porque pode ser útil em alguns casos. Por exemplo, usar traduções multi-idiomas em uma página.
O I18nProvider está acumulando os espaços para nome, para que você possa renomear os novos para manter os antigos.
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 >
)
}Tamanho : ~ 3,7kb?
O appWithI18n é usado internamente pelo Next Translate. Então, talvez você nunca precise disso . No entanto, o expomos na API, caso você desative a opção WebPack Loader e decidimos carregar os espaços para nome manualmente.
Se você deseja não usar o carregador Webpack, coloque -o no seu arquivo _app.js (e crie o arquivo _app.js se não o tiver).
Exemplo:
_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 ,
} ) Se skipInitialProps=true , você também deverá usar o Helper do LoadNamesPaces para carregar manualmente os espaços para nome em cada página.
Tamanho : ~ 1,9kb?
O loadNamespaces é usado internamente pelo Next Translate. Então, talvez você nunca precise disso . No entanto, o expomos na API, caso você desative a opção WebPack Loader e decidimos carregar os espaços para nome manualmente.
Para carregar os espaços para nome, você deve retornar em suas páginas os adereços que o ajudante fornece.
import loadNamespaces from 'next-translate/loadNamespaces'
export function getStaticProps ( { locale } ) {
return {
props : {
... ( await loadNamespaces ( { locale , pathname : '/about' } ) ) ,
}
}
} Para trabalhar bem, é necessário que seu _app.js seja embrulhado com o appwithi18n. Além disso, a propriedade loadLocaleFrom da configuração é obrigatória para defini -la.
Apoiamos 6 formulários plurais (retirados da página Plurais de CLDR) adicionando à chave esse sufixo (ou aninhando -o sob a chave sem _ prefixo):
_zero_one (singular)_two (duplo)_few (paucal)_many (também usado para frações se tiverem uma classe separada)_other (necessário - forma plural geral - também usada se o idioma tiver apenas um único formulário)Veja mais informações sobre plurais aqui .
Somente o _other é necessário porque é a única forma plural comum usada em todos os locais.
Todas as outras formas plurais depende do local. Por exemplo, o inglês tem apenas dois: _one e _other (1 gato vs. 2 gatos). Algumas línguas têm mais, como russo e árabe.
Além disso, também apoiamos uma correspondência exata especificando o número ( _0 , _999 ) e isso funciona para todos os locais. Aqui está um exemplo:
Código:
// **Note**: Only works if the name of the variable is {{count}}.
t ( 'cart-message' , { count } )Namespace:
{
"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
}ou
{
"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
}
}A API Intl.PluralRules está disponível apenas para navegadores modernos , se você quiser usá -lo em navegadores herdados, você deve adicionar um poli -preenchimento.
Você pode definir HTML dentro da tradução desta maneira:
{
"example-with-html" : " <0>This is an example <1>using HTML</1> inside the translation</0> "
}Exemplo:
import Trans from 'next-translate/Trans'
// ...
const Component = ( props ) => < p { ... props } />
// ...
< Trans
i18nKey = "namespace:example-with-html"
components = { [ < Component /> , < b className = "red" /> ] }
/ >Resultado renderizado:
< p > This is an example < b class =" red " > using HTML </ b > inside the translation </ p > Cada índice de matriz components corresponde a <index></index> da definição.
Na matriz components , não é necessário passar nos filhos de cada elemento. As crianças serão calculadas.
No espaço para nome, é possível definir chaves aninhadas como esta:
{
"nested-example" : {
"very-nested" : {
"nested" : " Nested example! "
}
}
}Para usá -lo, você deve usar "." como separador de identificação:
t `namespace:nested-example.very-nested.nested`Também é possível usar como matriz:
{
"array-example" : [
{ "example" : " Example {{count}} " },
{ "another-example" : " Another example {{count}} " }
]
} E obtenha todas as traduções da matriz com a opção returnObjects :
t ( 'namespace:array-example' , { count : 1 } , { returnObjects : true } )
/*
[
{ "example": "Example 1" },
{ "another-example": "Another example 1" }
]
*/ Além disso, é possível obter todas as traduções usando o Keyseparator como a chave, o padrão é '.' :
t ( 'namespace:.' , { count : 1 } , { returnObjects : true } )
/*
{
"array-example": [
{ "example": "Example 1" },
{ "another-example": "Another example 1" }
]
}
*/ Se não houver tradução, você poderá definir fallbacks ( string|string[] ) para pesquisar outras traduções:
const { t } = useTranslation ( )
const textOrFallback = t (
'ns:text' ,
{ count : 1 } ,
{
fallback : 'ns:fallback' ,
}
)Lista de fallbacks:
const { t } = useTranslation ( )
const textOrFallback = t (
'ns:text' ,
{ count : 42 } ,
{
fallback : [ 'ns:fallback1' , 'ns:fallback2' ] ,
}
)No componente trans:
< Trans
i18nKey = "ns:example"
components = { [ < Component /> , < b className = "red" /> ] }
values = { { count : 42 } }
fallback = { [ 'ns:fallback1' , 'ns:fallback2' ] } // or string with just 1 fallback
/> Você pode formatar parâmetros usando a função de configuração interpolation.format .
em 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
}
}
}No espaço para nome em inglês:
{
"example" : " The number is {{count, number}} "
}No espaço para nome espanhol:
{
"example" : " El número es {{count, number}} "
}Usando:
t ( 'example' , { count : 33.5 } )Retornos:
The number is 33.5El número es 33,5 Para alterar o idioma atual, você pode usar a navegação next.js (link e roteador) que passa no suporte locale .
Um exemplo de um possível componente ChangeLanguage usando o gancho useRouter do 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 >
)
} )
} Você também pode usar setLanguage para alterar o idioma, mantendo a mesma página.
import React from 'react'
import setLanguage from 'next-translate/setLanguage'
export default function ChangeLanguage ( ) {
return (
< button onClick = { async ( ) => await setLanguage ( 'en' ) } > EN </ button >
)
} Outra maneira de acessar a lista locales para alterar o idioma é usar o Next.js router A lista locales pode ser acessada usando o gancho Next.js Userouter.
Você pode definir um cookie chamado NEXT_LOCALE com o idioma definido pelo usuário como valor, dessa forma, um local pode ser forçado.
Exemplo de gancho:
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=/`
}
}
} Em alguns casos, quando a página está no idioma atual, convém fazer algumas exceções exibindo algum texto em outro idioma.
Nesse caso, você pode conseguir isso usando o I18nProvider .
Aprenda a fazer isso aqui.
Por padrão, o próximo translato usa o diretório de trabalho atual do processo node.js ( process.cwd() ).
Se você quiser alterá -lo, pode usar:
NEXT_TRANSLATE_PATH . Ele suporta caminho relativo e absolutoprocess.chdir(PATH_TO_NEXT_TRANSLATE) para mover o process.cwd() Quando se trata de componentes do servidor e componentes do cliente, pode ser um desafio carregar a mesma coisa em páginas diferentes. Para simplificar esse processo, extraímos toda a complexidade usando o next-translate-plugin .
Se você estiver interessado em aprender mais sobre como o próximo translato funciona com o novo paradigma do App Next.JS 13, consulte este artigo para obter uma explicação detalhada.
Se você usar a pasta "App" em vez da pasta "Páginas", a next-translate-plugin detectará automaticamente a alteração e você não precisará tocar em nenhuma das próximas configurações de translate. A única diferença é que a propriedade de configuração "Páginas" fará referência às páginas localizadas na pasta "App".
i18n.js
module . exports = {
locales : [ 'en' , 'ca' , 'es' ] ,
defaultLocale : 'en' ,
pages : {
'*' : [ 'common' ] ,
'/' : [ 'home' ] , // app/page.tsx
'/second-page' : [ 'home' ] , // app/second-page/page.tsx
} ,
} Simplesmente alterando a pasta "Páginas" para "aplicativo", você pode consumir traduções em suas páginas usando o gancho useTranslation ou o componente Trans . Você ainda verá o log (se habilitado) saber quais espaços para nome são carregados em cada página e tudo o mais deve ser o mesmo.
? Página/componente do servidor (+0kb): app/page.js :
import useTranslation from 'next-translate/useTranslation'
export default function HomePage ( ) {
const { t , lang } = useTranslation ( 'home' )
return < h1 > { t ( 'title' ) } </ h1 >
} ? Aste Página/componente do cliente (+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 >
} Em seguida.JS 10 Introduziu o suporte de roteamento I18N, permitindo que as páginas sejam renderizadas navegando para /es/page-name , onde as pages/page-name.js foram acessadas usando o gancho useRouter para obter o locale .
No entanto, como as páginas foram movidas das pages dir para o aplicativo DIR , esse roteamento i18n não funciona mais corretamente .
Na Next Translate, optamos por não implementar essa funcionalidade, pois pretendemos ser uma biblioteca para traduzir páginas, em vez de roteá-las. Esperamos que, no futuro, esse recurso seja implementado no diretório app .
Recomendamos o seguinte:
[lang] ao primeiro nível. Ou seja, todas as suas páginas estarão dentro /app/[lang] .i18n.(js|json) para conter o /[lang] no início. module.exports = {
locales: ['en', 'ca', 'es'],
defaultLocale: 'en',
pages: {
'*': ['common'],
- '/': ['home'],
+ '/[lang]': ['home'],
- '/second-page': ['home'],
+ '/[lang]/second-page': ['home'],
},
} No nível do próximo translato , já detectamos o idioma automaticamente de acordo com searchParams.get('lang') e params.lang . Portanto, você não precisa configurá-lo para cada página , pode usar next-translate normalmente nas páginas/componentes do servidor/cliente:
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 /> ] } />
</ >
)
} Há uma demonstração do next-translate no próximo.js repo:
Para usá -lo:
npx create-next-app --example with-next-translate with-next-translate-app
# or
yarn create next-app --example with-next-translate with-next-translate-appEsta demonstração está neste repositório:
git clone [email protected]:aralroca/next-translate.gitcd next-translateyarn && yarn example:basicSemelhante à demonstração básica, mas com alguns extras: TypeScript, Webpack 5, MDX, com _App.js na parte superior, páginas localizadas na pasta SRC/Páginas, carregando locais de SRC/traduções com uma estrutura diferente.
Esta demonstração está neste repositório:
git clone [email protected]:aralroca/next-translate.gitcd next-translateyarn && yarn example:complex Semelhante à demonstração complexa, mas com alguns extras: em vez da pasta pages , estamos usando a pasta App Next.js +13 com o novo sistema de layouts.
Esta demonstração está neste repositório:
git clone [email protected]:aralroca/next-translate.gitcd next-translateyarn && yarn example:with-app-directorySemelhante ao exemplo básico, mas carregando os namespaces de página desativando manualmente o carregador Webpack no arquivo de configuração i18n.json.
Não recomendamos que seja usado dessa maneira. No entanto, damos a oportunidade para alguém fazê -lo se não se sentir confortável com o nosso carregador de webpack.
Esta demonstração está neste repositório:
git clone [email protected]:aralroca/next-translate.gitcd next-translateyarn && yarn example:without-loader Obrigado a essas pessoas maravilhosas (key emoji):
Aral Roca Gomez ? | Vincent Ducorps | Björn Rave | Justin | Pol ? | Ademílson F. Tonato | Faul |
Bickmaev5 | Pierre Grimaud | Roman Minchyn | Egor | Darren | Giovanni Giordano | Eugene |
Andrew Chung | Thanh Minh | Crouton | Patrick | Vantroy | Joey | Gurkerl83 |
Teemu Perämäki | Luis Serrano | J-Schumann | Andre Hsu | Slevy85 | Bernd Artmüller | Rihards Ščeredins |
N4N5 | Rubén Moya | Tom Esterez | Dan Needham | Bruno Antunes | Kaan Atakan | Romain |
Arnau Jiménez | Edwin Veldhuizen | DUC ONG VIET | BILLEL HELALI | Wuif | Michał Bar | Wuif |
Marces Engel | Michał Bar | Arraste | Marces Engel | Vasco Silva | Vsevolod Volkov | Felix Yan |
Muhammad Al Ziqri | Marcelo Oliveira | Zack Sunderland | Fornos de Andrew | Dani | Mateusz Lesiak | Curetix |
Honza ? | Hardikbandhiya | Tim O. Peters | Li Ming | Fernando García Hernández | Hichem Fantar | Huseyin Onal |
Jesse Martin |
Este projeto segue a especificação de todos os contribuintes. Contribuições de qualquer tipo de boas -vindas!