Facile i18n pour next.js +10
Plugin suivant + API I18N
Note
Nous travaillons avec la version 3.0.0 de Next Translate. Ces derniers mois, nous avons été très concentrés sur Brisa . Donc, cela fait longtemps depuis la dernière version, mais nous n'avons pas oublié la transaction du prochain. Nous travaillons sur une nouvelle version qui apportera de nombreuses améliorations et nouvelles fonctionnalités. Nous sommes très heureux de le partager avec vous tous.

L'objectif principal de cette bibliothèque est de garder les traductions aussi simples que possible dans un environnement suivant.js.
Next Translate a deux parties: Plugin Next.js + API I18N .
Caractéristiques

Dans le fichier de configuration, vous spécifiez chaque page dont les espaces de noms ont besoin:
i18n.json
{
"pages" : {
"*" : [ "common" ] ,
"/" : [ "home" ] ,
"/cart" : [ "cart" ] ,
"/content/[slug]" : [ "content" ] ,
"rgx:^/account" : [ "account" ]
}
// rest of config here...
}Lisez ici comment ajouter les fichiers JSON Espaces JSON.
Next Translate garantit que chaque page n'a que ses espaces de noms avec la langue actuelle. Donc, si nous avons 100 lieux, seulement 1 sera chargé.
Pour ce faire, nous utilisons un chargeur WebPack qui charge les fichiers de traduction nécessaires dans les méthodes suivant.js ( getStaticProps , getServersIDEPROPS ou getInitialProps ). Si vous avez déjà une de ces méthodes sur votre page, le webpack chargeur utilisera votre propre méthode, mais les défauts qu'il utilisera sont:
getStaticProps . Il s'agit de la méthode par défaut utilisée sur la plupart des pages , sauf si c'est une page spécifiée dans les deux points suivants. Ceci est pour les performances, donc les calculs sont effectués en temps de construction au lieu du temps de demande.getServerSideProps . Il s'agit de la méthode par défaut pour les pages dynamiques comme [slug].js ou [...catchall].js . En effet, pour ces pages, il est nécessaire de définir les getStaticPaths et il n'y a aucune connaissance de la façon dont les limaces devraient être pour chaque lieu. De même, comment se fait-il par défaut, seulement que vous écrivez les GetStaticPaths, alors il utilisera déjà les GetStaticProps pour charger les traductions.getInitialProps . Il s'agit de la méthode par défaut pour ces pages qui utilisent un hoc . C'est pour éviter les conflits car HOC pourrait écraser un getInitialProps . Tout ce processus est transparent , donc dans vos pages, vous pouvez consommer directement le crochet useTranslation pour utiliser les espaces de noms, et vous n'avez rien à faire d'autre.
Si pour une raison quelconque, vous utilisez un getInitialProps dans votre fichier _app.js , les traductions ne seront chargées que dans vos getInitialProps à partir de _app.js . Nous recommandons que pour des raisons d'optimisation, vous n'utilisez pas cette approche, sauf si elle est absolument nécessaire.
yarn add next-translate Le next-translate-plugin est un outil qui permet aux développeurs de gérer efficacement les traductions sur une base page par page pendant le processus de construction. Il est distinct du package next-translate , qui permet aux développeurs d'accéder aux traductions dans le code où il est nécessaire. Le plugin fonctionne en analysant toutes les pages, en recherchant les traductions et en réécrivant le fichier de page en ajoutant les traductions. Cela fait du plugin une solution plus efficace et flexible pour gérer les traductions dans une application Next.js. Il est recommandé d'installer le plugin en tant que DevDependance.
yarn add next-translate-plugin -DDans votre fichier suivant.config.js :
const nextTranslate = require ( 'next-translate-plugin' )
module . exports = nextTranslate ( ) Ou si vous avez déjà le fichier Next.config.js et souhaitez y garder les modifications, passez l'objet config à nextTranslate() . Par exemple pour WebPack, vous pouvez le faire comme ceci:
const nextTranslate = require ( 'next-translate-plugin' )
module . exports = nextTranslate ( {
webpack : ( config , { isServer , webpack } ) => {
return config ;
}
} ) Ajoutez un fichier de configuration i18n.json (ou i18n.js avec module.exports ) dans la racine du projet. Chaque page doit avoir ses espaces de noms. Jetez un œil sur la section Configuration pour plus de détails.
{
"locales" : [ " en " , " ca " , " es " ],
"defaultLocale" : " en " ,
"pages" : {
"*" : [ " common " ],
"/" : [ " home " , " example " ],
"/about" : [ " about " ]
}
}Dans le fichier de configuration, vous pouvez utiliser à la fois la configuration que nous avons spécifiée ici et les propres fonctionnalités sur l'internationalisation de Next.js 10.
Par défaut, les espaces de noms sont spécifiés dans le répertoire racine / Localives de cette manière:
/ Lays
.
├── ca
│ ├── common.json
│ └── home.json
├── en
│ ├── common.json
│ └── home.json
└── es
├── common.json
└── home.json Chaque nom de fichier correspond à l'espace de noms spécifié sur la propriété de configuration pages , tandis que chaque contenu de fichier doit être similaire à ceci:
{
"title" : " Hello world " ,
"variable-example" : " Using a variable {{count}} "
}Cependant, vous pouvez utiliser une autre destination pour enregistrer vos fichiers d'espaces de noms à l'aide de la propriété de configuration LoadLocaleFrom:
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 ) ,
}Ensuite, utilisez les traductions dans la page et ses composants:
pages / exemple.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>
}Vous pouvez consommer les traductions directement sur vos pages, vous n'avez pas à vous soucier de charger manuellement les fichiers d'espaces de noms sur chaque page. Le plugin translastique suivant charge uniquement les espaces de noms dont la page a besoin et uniquement avec la langue actuelle.
Dans le fichier de configuration, vous pouvez utiliser à la fois la configuration que nous avons spécifiée ici et les propres fonctionnalités sur l'internationalisation de Next.js 10.
| Option | Description | Taper | Défaut |
|---|---|---|---|
defaultLocale | ISO du paramètre par défaut ("EN" par défaut). | string | "en" |
locales | Un tableau avec toutes les langues à utiliser dans le projet. | string[] | [] |
loadLocaleFrom | Modifiez la façon dont vous chargez les espaces de noms. | function qui renvoie une Promise avec le JSON . | Par défaut, le chargement des espaces de noms à partir du répertoire racine des locaux . |
pages | Un objet qui définit les espaces de noms utilisés dans chaque page. Exemple d'objet: {"/": ["home", "example"]} . Pour ajouter des espaces de noms à toutes les pages, vous devez utiliser la clé "*" , ex: {"*": ["common"]} . Il est également possible d'utiliser Regex en utilisant rgx: sur Front: {"rgx:/form$": ["form"]} . Vous pouvez également utiliser une fonction au lieu d'un tableau, pour fournir des espaces de noms en fonction de certaines règles, ex: { "/": ({ req, query }) => query.type === 'example' ? ['example'] : []} | Object<string[] or function> | {} |
logger | Fonction pour enregistrer les clés manquantes dans le développement et la production. Si vous utilisez i18n.json comme fichier de configuration, vous devez le modifier en i18n.js | function | Par défaut, l'enregistreur est une fonction faisant une console.warn uniquement en développement. |
loggerEnvironment | String pour définir si le journaliste doit s'exécuter dans le navigateur, dans le nœud ou les deux | "node" | "browser" | "both" | "browser" |
logBuild | Chaque page a un journal indiquant: espaces de noms, langue et méthode actuelles utilisées pour charger les espaces de noms. Avec cela, vous pouvez le désactiver. | Boolean | true |
loader | Si vous souhaitez désactiver le chargeur WebPack et charger manuellement les espaces de noms sur chaque page, nous vous donnons la possibilité de le faire en désactivant cette option. | Boolean | true |
interpolation | Modifiez le délimiteur utilisé pour l'interpolation. | {prefix: string; suffix: string, formatter: function } | {prefix: '{{', suffix: '}}'} |
keySeparator | Changez le séparateur utilisé pour les clés imbriquées. Défini sur false pour désactiver les touches nidiques dans des fichiers de traduction JSON. Peut être utile si vous souhaitez utiliser du texte naturel comme clés. | string | false | '.' |
nsSeparator | Char pour diviser l'espace de noms de la clé. Vous devez le définir sur false si vous souhaitez utiliser du texte naturel comme clés. | string | false | ':' |
defaultNS | Espace de noms par défaut utilisé s'il n'est pas transmis à useTranslation ou dans la touche de traduction. | string | undefined |
staticsHoc | Les HOC que nous avons dans notre API (appwithi18n), n'utilisent pas les statiques de hoist-non-réact afin de ne pas inclure plus de KB que nécessaire (des valeurs statiques différentes de GetInitialProps dans les pages sont rarement utilisées) . Si vous avez un conflit avec des statistiques, vous pouvez ajouter ici le palan-non-réaction (ou toute autre alternative). Voir un exemple. | Function | null |
extensionsRgx | Modifiez le regex utilisé par le chargeur WebPack pour trouver les pages suivantes. | Regex | /.(tsx|ts|js|mjs|jsx)$/ |
revalidate | Si vous souhaitez que un revalidate par défaut sur chaque page, nous vous donnons la possibilité de le faire en transmettant un numéro pour revalider. Vous pouvez toujours définir GetStaticProps sur une page avec un montant de revalidate différent et remplacer cette remplacement par défaut. | Number | Si vous ne le définissez pas, par défaut, les pages n'auront pas de revalide. |
pagesInDir | Si vous exécutez next ./my-app pour changer où se trouvent vos pages, vous pouvez ici définir my-app/pages afin que le prochain trafic puisse deviner où ils se trouvent. | String | Si vous ne le définissez pas, par défaut, les pages seront recherchées dans les endroits classiques comme pages et src/pages . |
localesToIgnore | Indiquez ces localités à ignorer lorsque vous préfixez les paramètres régionaux par défaut à l'aide d'un middleware (dans le prochain +12, apprenez à le faire) | Array<string> | ['default'] |
allowEmptyStrings | Changez comment les chaînes vides traduites doivent être gérées. S'il est omis ou passé comme vrai, il renvoie une chaîne vide. S'il est passé comme faux, renvoie le nom de clé lui-même (y compris NS). | Boolean | true |
Taille : ~ 150B?
Ce crochet est le moyen recommandé d'utiliser des traductions dans vos pages / composants.
Exemple:
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 >
< >
)
} La fonction t :
i18nKey . Similaire que useTranslation mais sans être un crochet. Cet assistant ne fonctionne que dans l'application Dir .
const { t , lang } = createTranslation ( 'ns1' ) // default namespace (optional)
const title = t ( 'title' )Taille : ~ 560B?
C'est une alternative au crochet useTranslation , mais dans un hoc pour ces composants qui ne sont pas fonctionnels. (Non recommandé, il est préférable d'utiliser le crochet useTranslation .) .
Le withTranslation HOC renvoie un composant avec un accessoire supplémentaire nommé i18n (objet {t: function, lang: string}).
Exemple:
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 ) Semblable à useTranslation("common") vous pouvez appeler withTranslation avec le deuxième paramètre définissant un espace de noms par défaut à utiliser:
export default withTranslation(NoFunctionalComponent, "common")
Taille : ~ 1,4 Ko?
Parfois, nous devons faire des traductions avec HTML à l'intérieur du texte (gras, liens, etc.), le composant Trans est exactement ce dont vous avez besoin. Nous vous recommandons d'utiliser ce composant uniquement dans ce cas, pour d'autres cas, nous recommandons fortement l'utilisation du crochet useTranslation à la place.
Exemple:
// 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 en utilisant components Prop comme objet:
// 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 - Array | Objet - En cas de tableau, chaque index correspond à la balise définie <0> / <1> . En cas d'objet, chaque touche correspond à la balise définie <example> .values - objet - paramètres de requêtefallback - String | String [] - Facultatif. Fallback i18nkey si le i18nkey ne correspond pas.defaultTrans - String - Traduction par défaut pour la clé. Si les touches de secours sont utilisées, elle ne sera utilisée qu'après avoir épuisé toutes les replies.ns - Espace de noms à utiliser quand aucun n'est intégré dans i18nKeyreturnObjects - Boolean - Obtenez une partie du JSON avec toutes les traductions. Voir plus. Dans les i18nKey où nous avons besoin de la fonctionnalité du composant Trans , mais avons besoin d'une chaîne pour être interpolée, plutôt que de la sortie de la fonction t(props.i18nKey) , il existe également un composant TransText , qui prend une text
text - String - La chaîne qui (éventuellement) contient des balises nécessitant une interpolationcomponents - Array | Objet - Cela se comporte exactement comme Trans (voir ci-dessus). Ceci est particulièrement utile lors du mappage sur la sortie d'un t() avec 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 /> ,
} }
/>
) }Taille : ~ 1,5 Ko?
Le composant DynamicNamespaces est utile pour charger des espaces de noms dynamiques, par exemple dans les modaux.
Exemple:
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 >
)
} N'oubliez pas que l'espace de noms ['dynamic'] ne doit pas être répertorié sur la configuration pages :
pages: {
'/my-page' : [ 'common' ] , // only common namespace
}namespaces - String [] - Liste des espaces de noms dynamiques à télécharger - requis .fallback - ReactNode - Fallback à afficher en attendant les espaces de noms chargent. - Facultatif .dynamic - Fonction - Par défaut, il utilise le LoadLocaleFrom dans la configuration pour charger les espaces de noms, mais vous pouvez spécifier une autre destination. - Facultatif .Taille : ~ 1,3 Ko?
Fonction asynchrone pour charger la fonction t à l'extérieur des composants / pages. Il fonctionne à la fois sur côté serveur et côté client.
Contrairement au crochet Usetranslation, nous pouvons utiliser ici n'importe quel espace de noms, il ne faut pas être un espace de noms défini dans la configuration "pages". Il télécharge l'espace de noms indiqué comme un paramètre sur l'exécution.
Vous pouvez charger plusieurs espaces de noms en donnant un tableau en tant que paramètre, dans ce cas, l'espace de noms par défaut sera celui de Fist.
Exemple à l'intérieur 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 } }
}Exemple intérieur API Route:
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 } ) )
}Exemple de chargement plusieurs espaces de noms:
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 } ) )
}Taille : ~ 3KB?
Le I18nProvider est un fournisseur de contexte utilisé en interne par le translastique suivant pour fournir le lang actuel et les espaces de noms de page. Alors peut-être que vous n'en aurez jamais besoin .
Cependant, il est exposé à l'API car il peut être utile dans certains cas. Par exemple, pour utiliser des traductions multi-langues dans une page.
Le I18nProvider accumule les espaces de noms, vous pouvez donc renommer les nouveaux afin de garder les anciens.
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 >
)
}Taille : ~ 3,7 Ko?
L' appWithI18n est utilisé en interne par la translation suivante. Alors peut-être que vous n'en aurez jamais besoin . Cependant, nous l'exposons dans l'API au cas où vous désactivez l'option WebPack Loader et décidiez de charger les espaces de noms manuellement.
Si vous ne souhaitez pas utiliser le chargeur WebPack, vous devez le mettre dans votre fichier _app.js (et créer le fichier _app.js si vous ne l'avez pas).
Exemple:
_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 ,
} ) Si skipInitialProps=true , vous devez également utiliser l'assistance LoadNamespaces pour charger manuellement les espaces de noms sur chaque page.
Taille : ~ 1,9 Ko?
Les loadNamespaces sont utilisés en interne par la transformation suivante. Alors peut-être que vous n'en aurez jamais besoin . Cependant, nous l'exposons dans l'API au cas où vous désactivez l'option WebPack Loader et décidiez de charger les espaces de noms manuellement.
Pour charger les espaces de noms, vous devez retourner dans vos pages les accessoires fournis par l'assistance.
import loadNamespaces from 'next-translate/loadNamespaces'
export function getStaticProps ( { locale } ) {
return {
props : {
... ( await loadNamespaces ( { locale , pathname : '/about' } ) ) ,
}
}
} Pour bien fonctionner, il est nécessaire que votre _app.js soit enveloppé avec l'Appwithi18n. De plus, la propriété de configuration loadLocaleFrom est obligatoire pour la définir.
Nous prenons en charge 6 formulaires pluriels (tirés de la page Plurals CLDR) en ajoutant à la clé ce suffixe (ou en le niant sous la clé sans _ préfixe):
_zero_one (singulier)_two (double)_few (Paucal)_many (également utilisé pour les fractions s'ils ont une classe séparée)_other (requis - forme plurielle générale - également utilisée si la langue n'a qu'une seule forme)Voir plus d'informations sur les pluriels ici .
Seul le dernier, _other , est requis car c'est la seule forme plurielle commune utilisée dans tous les lieux.
Toutes les autres formes plurielles dépendent des paramètres régionaux. Par exemple, l'anglais n'en a que deux: _one et _other (1 chat contre 2 chats). Certaines langues ont plus, comme le russe et l'arabe.
De plus, nous prenons également en charge une correspondance exacte en spécifiant le numéro ( _0 , _999 ) et cela fonctionne pour tous les lieux. Voici un exemple:
Code:
// **Note**: Only works if the name of the variable is {{count}}.
t ( 'cart-message' , { count } )Espace de noms:
{
"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
}
}L'API intl.PluralRules est uniquement disponible pour les navigateurs modernes , si vous souhaitez l'utiliser dans les navigateurs hérités, vous devez ajouter un polyfill.
Vous pouvez définir HTML à l'intérieur de la traduction de cette façon:
{
"example-with-html" : " <0>This is an example <1>using HTML</1> inside the translation</0> "
}Exemple:
import Trans from 'next-translate/Trans'
// ...
const Component = ( props ) => < p { ... props } />
// ...
< Trans
i18nKey = "namespace:example-with-html"
components = { [ < Component /> , < b className = "red" /> ] }
/ >Résultat rendu:
< p > This is an example < b class =" red " > using HTML </ b > inside the translation </ p > Chaque index du tableau components correspond à <index></index> de la définition.
Dans le tableau components , il n'est pas nécessaire de passer les enfants de chaque élément. Les enfants seront calculés.
Dans l'espace de noms, il est possible de définir des clés imbriquées comme ceci:
{
"nested-example" : {
"very-nested" : {
"nested" : " Nested example! "
}
}
}Pour l'utiliser, vous devez utiliser "." comme séparateur d'ID:
t `namespace:nested-example.very-nested.nested`Il est également possible d'utiliser comme tableau:
{
"array-example" : [
{ "example" : " Example {{count}} " },
{ "another-example" : " Another example {{count}} " }
]
} Et obtenez toutes les traductions du tableau avec l'option returnObjects :
t ( 'namespace:array-example' , { count : 1 } , { returnObjects : true } )
/*
[
{ "example": "Example 1" },
{ "another-example": "Another example 1" }
]
*/ Il est également possible d'obtenir toutes les traductions en utilisant le SECTINGSEPARATOR comme clé, par défaut est '.' :
t ( 'namespace:.' , { count : 1 } , { returnObjects : true } )
/*
{
"array-example": [
{ "example": "Example 1" },
{ "another-example": "Another example 1" }
]
}
*/ Si aucune traduction n'existe, vous pouvez définir les secours ( string|string[] ) pour rechercher d'autres traductions:
const { t } = useTranslation ( )
const textOrFallback = t (
'ns:text' ,
{ count : 1 } ,
{
fallback : 'ns:fallback' ,
}
)Liste des replies:
const { t } = useTranslation ( )
const textOrFallback = t (
'ns:text' ,
{ count : 42 } ,
{
fallback : [ 'ns:fallback1' , 'ns:fallback2' ] ,
}
)Dans le composant trans:
< Trans
i18nKey = "ns:example"
components = { [ < Component /> , < b className = "red" /> ] }
values = { { count : 42 } }
fallback = { [ 'ns:fallback1' , 'ns:fallback2' ] } // or string with just 1 fallback
/> Vous pouvez formater les paramètres à l'aide de la fonction interpolation.format Config.
Dans 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
}
}
}Dans l'espace de noms en anglais:
{
"example" : " The number is {{count, number}} "
}Dans l'espace de noms espagnol:
{
"example" : " El número es {{count, number}} "
}En utilisant:
t ( 'example' , { count : 33.5 } )Renvoie:
The number is 33.5El número es 33,5 Afin de modifier la langue actuelle, vous pouvez utiliser la navigation locale .
Un exemple de composant ChangeLanguage possible à l'aide du crochet useRouter de 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 >
)
} )
} Vous pouvez également utiliser setLanguage pour changer la langue tout en gardant la même page.
import React from 'react'
import setLanguage from 'next-translate/setLanguage'
export default function ChangeLanguage ( ) {
return (
< button onClick = { async ( ) => await setLanguage ( 'en' ) } > EN </ button >
)
} Une autre façon d'accéder à la liste locales pour modifier la langue consiste à utiliser le Next.js router . La liste locales est accessible à l'aide du crochet userouter suivant.
Vous pouvez définir un cookie nommé NEXT_LOCALE avec la langue définie par l'utilisateur comme valeur, de cette façon, un lieu peut être forcé.
Exemple de crochet:
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=/`
}
}
} Dans certains cas, lorsque la page est dans la langue actuelle, vous voudrez peut-être faire des exceptions affichant du texte dans une autre langue.
Dans ce cas, vous pouvez y parvenir en utilisant le I18nProvider .
Apprenez à le faire ici.
Next Translate utilise par défaut le répertoire de travail actuel du processus Node.js ( process.cwd() ).
Si vous souhaitez le changer, vous pouvez utiliser:
NEXT_TRANSLATE_PATH . Il prend en charge à la fois un chemin relatif et absoluprocess.chdir(PATH_TO_NEXT_TRANSLATE) pour déplacer le process.cwd() En ce qui concerne les composants du serveur et les composants clients, il peut être difficile de charger la même chose sur différentes pages. Pour simplifier ce processus, nous avons extrait toute la complexité en utilisant le next-translate-plugin .
Si vous êtes intéressé à en savoir plus sur le fonctionnement de la transaction suivante avec le nouveau paradigm de l'application Next.js 13, consultez cet article pour une explication détaillée.
Si vous utilisez le dossier "App" au lieu du dossier "Pages", le next-translate-plugin détectera automatiquement le changement, et vous n'aurez pas besoin de toucher aucune des configurations de translate suivante. La seule différence est que la propriété de configuration "pages" référendra les pages situées dans le dossier "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
} ,
} En modifiant simplement le dossier "Pages" en "application", vous pouvez consommer des traductions dans vos pages à l'aide du crochet useTranslation ou du composant Trans . Vous verrez toujours le journal (si vous êtes activé) de savoir quels espaces de noms sont chargés sur chaque page, et tout le reste devrait être le même.
? Page de serveur / composant (+ 0KB): app/page.js :
import useTranslation from 'next-translate/useTranslation'
export default function HomePage ( ) {
const { t , lang } = useTranslation ( 'home' )
return < h1 > { t ( 'title' ) } </ h1 >
} ? ️ Page / composant client (+ 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 a introduit le support de routage i18n, permettant à des pages d'être rendues en naviguant vers /es/page-name , où les pages/page-name.js ont été accessibles à l'aide du crochet useRouter pour obtenir le locale .
Cependant, depuis que les pages ont été déplacées des pages DIR au DIR de l'application , ce routage i18n ne fonctionne plus correctement .
Chez Next Translate, nous avons choisi de ne pas réimplémenter cette fonctionnalité, car nous visons à être une bibliothèque pour traduire des pages, plutôt que de les acheminer. Nous espérons qu'à l'avenir, cette fonctionnalité sera implémentée dans le répertoire app .
Nous recommandons ce qui suit:
[lang] au premier niveau. Autrement dit, toutes vos pages seront à l'intérieur /app/[lang] .i18n.(js|json) pour contenir le /[lang] au début. module.exports = {
locales: ['en', 'ca', 'es'],
defaultLocale: 'en',
pages: {
'*': ['common'],
- '/': ['home'],
+ '/[lang]': ['home'],
- '/second-page': ['home'],
+ '/[lang]/second-page': ['home'],
},
} Au niveau de la translation suivante, nous détectons déjà la langue automatiquement selon searchParams.get('lang') et params.lang . Ainsi, vous n'avez pas besoin de le configurer pour chaque page , vous pouvez utiliser next-translate comme d'habitude dans les pages / composants du serveur / client:
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 /> ] } />
</ >
)
} Il y a une démo de next-translate sur le repo suivant.js:
Pour l'utiliser:
npx create-next-app --example with-next-translate with-next-translate-app
# or
yarn create next-app --example with-next-translate with-next-translate-appCette démo est dans ce référentiel:
git clone [email protected]:aralroca/next-translate.gitcd next-translateyarn && yarn example:basicSimilaire que la démo de base mais avec certains extras: TypeScript, WebPack 5, MDX, avec _App.js en haut, pages situées sur le dossier SRC / Pages, chargeant des lieux de SRC / Traductions avec une structure différente.
Cette démo est dans ce référentiel:
git clone [email protected]:aralroca/next-translate.gitcd next-translateyarn && yarn example:complex Similaire que la démo complexe mais avec quelques-uns supplémentaires: au lieu du dossier pages , nous utilisons le dossier d'application Next.js +13 avec le nouveau système de disposition.
Cette démo est dans ce référentiel:
git clone [email protected]:aralroca/next-translate.gitcd next-translateyarn && yarn example:with-app-directorySimilaire que l'exemple de base mais chargeant les espaces de noms de page désactivant manuellement le chargeur WebPack dans le fichier de configuration i18n.json.
Nous ne recommandons pas qu'il soit utilisé de cette manière. Cependant, nous donnons la possibilité à quiconque de le faire s'il n'est pas à l'aise avec notre chargeur WebPack.
Cette démo est dans ce référentiel:
git clone [email protected]:aralroca/next-translate.gitcd next-translateyarn && yarn example:without-loader Merci à ces gens merveilleux (clé emoji):
Aral Roca Gomez ? | Vincent Ducorps | Rave björn | Justin | Pol ? | Ademílson F. Tonato | Faul |
bickmaev5 | Pierre Grimaud | Roman Minchyn | Égor à | Darren | Giovanni giordano | Eugene |
Andrew Chung | Thanh Minh | croûton | Patrick | Vantroy | Joey | gurkerl83 |
Teemu perämäki | Luis Serrano | J-Schumann | Andre Hsu | Slow85 | Bernd Artmüller | Rihards ščeredins |
N4N5 | Rubén Moya | Tom Esterez | Dan Needham | Bruno Antunes | Kaan Atakan | Romain |
Arnau Jiménez | Edwin Veldhuizen | Ngo duc viet | Billel Helali | Wuif | Michał Bar | Wuif |
Marces Engel | Michał Bar | Faire glisser | Marces Engel | Vasco Silva | Vsevolod Volkov | Felix Yan |
Muhammad al Ziqri | Marcelo Oliveira | Zack Sunderland | Fours Andrew | dani | Mateusz Lesiak | Curetix |
Honza ? | Forkbandhiya | Tim O. Peters | Li ming | Fernando García Hernández | Hichem Fantar | Huseyin onal |
Jesse Martin |
Ce projet suit les spécifications de tous les contributeurs. Contributions de toute nature bienvenue!