Le routage internationalisé n'est pas exactement une nouvelle fonctionnalité sur Next.js. (Il est disponible depuis v.10 .) Dans cet article, nous vérifions non seulement ce que nous obtenons de cette fonctionnalité, mais aussi comment tirer parti de ces fonctionnalités pour obtenir la meilleure expérience utilisateur et un développeur fluide. expérience aussi. Continuez à lire si vous aimez le code auto-documenté, les tailles de bundles maigres et les erreurs de compilation au lieu des erreurs d'exécution.
Instruire Next.js que votre application a l'intention d'avoir des itinéraires pour différents paramètres régionaux (ou pays, ou les deux) ne pourrait pas être plus fluide. A la racine de votre projet, créez un next.config.js
si vous n'en avez pas eu besoin. Vous pouvez copier à partir de cet extrait.
/** @type {import('next').NextConfig} */
module.exports = {
reactStrictMode : vrai,
i18n : {
paramètres régionaux : ['en', 'gc'],
defaultLocale : 'fr',
}
}
Remarque : La première ligne laisse le serveur TS (si vous êtes sur un projet TypeScript ou si vous utilisez VSCode) quelles sont les propriétés prises en charge dans l'objet de configuration. Ce n'est pas obligatoire, mais c'est certainement une fonctionnalité intéressante.
Vous noterez deux clés de propriété à l'intérieur de l'objet i18n
:
locales
Une liste de tous les paramètres régionaux pris en charge par votre application. Il s'agit d'untableau
dechaînes
.defaultLocale
La locale de votre racine principale. C'est le paramètre par défaut lorsqu'aucune préférence n'est trouvée ou que vous forcez à la racine.
Ces valeurs de propriété détermineront les routes, alors n'allez pas trop loin avec elles. Créez-en des valides en utilisant le code local et/ou codes pays et respectez les minuscules car ils généreront bientôt une url
.
Maintenant, votre application a plusieurs paramètres régionaux pris en charge, il y a une dernière chose dont vous devez être conscient dans Next.js. Chaque route existe désormais sur chaque locale, et le framework sait qu'elles sont identiques. Si vous souhaitez naviguer vers une locale spécifique, nous devons fournir un accessoire locale
à notre composant Link
sinon, il reviendra en fonction de la Accept-Language[dunavigateur
en-tête.
Page d'accueil en allemand
Finalement, vous voudrez écrire une ancre qui obéira simplement aux paramètres régionaux sélectionnés pour l'utilisateur et les enverra à la route appropriée. Cela peut facilement être réalisé avec le crochet personnalisé useRouter
de Next.js, il vous renverra un object
et la locale
sélectionnée sera une clé
là-dedans.
type d'importation { FC } à partir de 'react'
importer le lien depuis 'suivant/lien'
importer { useRouter } depuis 'next/router'
const Ancre : FC = ({ href, enfants }) => {
const { locale } = useRouter()
revenir (
{enfants}
)
}
Votre Next.js est maintenant entièrement préparé pour l'internationalisation. Il va :
- Récupérer les paramètres régionaux préférés de l'utilisateur à partir de l'en-tête
Accepted-Languages
dans notre demande : avec l'aimable autorisation de Next.js ; - Envoyer l'utilisateur toujours vers un itinéraire obéissant à la préférence de l'utilisateur : en utilisant notre composant
Anchor
créé ci-dessus ; - Retour à la langue par défaut si nécessaire.
La dernière chose que nous devons faire est de nous assurer que nous pouvons gérer les traductions. Pour le moment, le routage fonctionne parfaitement, mais il n'y a aucun moyen d'ajuster le contenu de chaque page.
Créer un dictionnaire
Peu importe si vous utilisez un service de gestion de traduction ou obtenez vos textes d'une autre manière, ce que nous voulons en fin de compte est un objet JSON pour notre JavaScript à consommer pendant l'exécution. Next.js propose trois environnements d'exécution différents :
- côté client,
- côté serveur,
- compile-time.
Mais gardez cela en tête pour le moment. Nous devrons d'abord structurer nos données.
Les données à traduire peuvent varier en fonction de l'outil qui les entoure, mais en fin de compte, elles se résument finalement aux paramètres régionaux, aux clés et aux valeurs. C'est donc par cela que nous allons commencer. Mes paramètres régionaux seront en
pour l'anglais et pt
pour le portugais.
module.exports = {
fr : {
bonjour : « bonjour le monde »
},
point : {
bonjour : 'oi mundo'
}
}
Crochet personnalisé de traduction
Avec cela à portée de main, nous pouvons maintenant créer notre crochet personnalisé de traduction.
import { useRouter } à partir de 'next/router'
importer le dictionnaire de './dictionary'
export const useTranslation = () => {
const { locales = []defaultLocale, ...nextRouter} = useRouter()
const locale = locales.includes(nextRouter.locale || '')
? nextRouter.locale
: defaultLocale
revenir {
traduire : (terme) => {
const translation = dictionnaire[locale][term]
retour booléen(traduction) ? traduction : terme
}
}
}
Décomposons ce qui se passe à l'étage :
- Nous utilisons
useRouter
pour obtenir tous les paramètres régionaux disponibles, celui par défaut et le paramètre actuel ; - Une fois que nous avons cela, nous vérifions si nous avons une locale valide avec nous, si nous ne le faisons pas : retour à la locale par défaut ;
- Nous retournons maintenant la méthode
translate
. Il prend unterm
et le récupère du dictionnaire vers les paramètres régionaux spécifiés. S'il n'y a pas de valeur, il renvoie à nouveau la traductionterm
.
Maintenant, notre application Next.js est prête à traduire au moins les cas les plus courants et rudimentaires. Veuillez noter qu'il ne s'agit pas d'un dunk sur les bibliothèques de traduction. Il y a des tonnes de fonctionnalités importantes notre hook personnalisé là-bas manque : interpolation, pluralisation, genres, etc.
Time To Scale
Le manque de fonctionnalités de notre hook personnalisé est acceptable si nous n'en avons pas besoin maintenant; il est toujours possible (et sans doute mieux) de mettre en œuvre des choses lorsque vous en avez réellement besoin. Mais il y a un problème fondamental avec notre stratégie actuelle qui est inquiétant : elle n'exploite pas l'aspect isomorphe de Next.js.
Le pire aspect de la mise à l'échelle des applications localisées est de ne pas gérer les actions de traduction elles-mêmes. Ce morceau a été fait à plusieurs reprises et est quelque peu prévisible. Le problème est de faire face à la lourdeur de l'envoi de dictionnaires sans fin vers le navigateur – et ils ne font que se multiplier à mesure que votre application nécessite de plus en plus de langues. Ce sont des données qui deviennent très souvent inutiles pour l'utilisateur final, ou qui affectent les performances si nous devons récupérer de nouvelles clés et valeurs lorsqu'ils changent de langue. S'il y a une grande vérité sur l'expérience utilisateur, c'est celle-ci : vos utilisateurs vous surprendront.
Nous ne pouvons pas prédire quand ou si les utilisateurs changeront de langue ou auront besoin de cette clé supplémentaire. Ainsi, idéalement, nos applications auront toutes les traductions d'un itinéraire spécifique à portée de main lorsqu'un tel itinéraire est chargé. Pour l'instant, nous devons diviser des morceaux de notre dictionnaire en fonction de ce que la page rend et des permutations d'état qu'elle peut avoir. Ce terrier de lapin va en profondeur.
Pré-rendu côté serveur
Il est temps de récapituler nos nouvelles exigences en matière d'évolutivité :
- Expédier le moins possible côté client ;
- Éviter les demandes supplémentaires basées sur l'utilisateur interaction;
- Envoyer le premier rendu déjà traduit à l'utilisateur.
Grâce à la méthode getStaticProps
des pages Next.js, nous pouvons y parvenir sans avoir à plonger du tout dans la configuration du compilateur. Nous importerons l'intégralité de notre dictionnaire dans cette fonction spéciale sans serveur et nous enverrons à notre page une liste d'objets spéciaux contenant les traductions de chaque clé.
Configuration des traductions SSR
Retour à notre application, nous créerons un nouvelle méthode. Définissez un répertoire comme /utils
ou /helpers
et quelque part à l'intérieur, nous aurons ce qui suit :
export function ssrI18n(key, dictionary) {
return Object.keys(dictionnaire)
.reduce((keySet, locale) => {
keySet[locale] = (dictionnaire[locale as keyof typeof dictionary][key])
return keySet
, {})
}
Décomposer ce que nous faisons :
- Prenez la traduction
key
outerm
et ledictionary
; - Tournez le
dictionnaire
dans un tableau de sesclés
; - Chaque clé du dictionnaire est une
locale
nous créons donc un objet avec laclé
name et chaquelocale
sera la valeur pour cette langue spécifique.
Un exemple de sortie de cette méthode aura la forme suivante :
{
'Bonjour': {
'fr': 'Bonjour tout le monde',
'pt' : 'Oi Mundo',
'de' : 'Bonjour Welt'
}
}
Nous pouvons maintenant passer à notre page Next.js.
import { ssrI18n } de '../utils/ssrI18n'
importer { DICTIONNAIRE } de '../dictionnaire'
importer { useRouter } depuis 'next/router'
const Accueil = ({ bonjour }) => {
const router = useRouter()
const i18nLocale = getLocale (routeur)
revenir (
{bonjour[i18nLocale]}
)
}
export const getStaticProps = async () => ({
accessoires : {
bonjour : ssrI18n('bonjour', DICTIONNAIRE),
// ajoute une autre entrée à chaque clé de traduction
}
})
Et avec ça, c'est fini ! Nos pages ne reçoivent exactement que les traductions dont elles auront besoin dans toutes les langues. Pas de demandes externes s'ils changent de langue à mi-chemin, au contraire : l'expérience sera super rapide.
Skipping All Setup
C'est bien, mais nous pouvons encore faire mieux pour nous-mêmes. Le développeur pourrait prendre un peu d'attention; il y a beaucoup d'amorçage dedans, et nous comptons toujours sur ne pas faire de fautes de frappe. Si vous avez déjà travaillé sur des applications traduites, vous saurez qu'il y aura une clé mal tapée quelque part, d'une manière ou d'une autre. Ainsi, nous pouvons apporter la sécurité de type de TypeScript à nos méthodes de traduction. Il s'agit d'une petite bibliothèque qui fait exactement ce que nous avons fait ci-dessus, mais ajoute des types et quelques cloches et sifflets supplémentaires. js Internationalized Routing peut faire pour que votre application atteigne la mondialisation, et ce que cela signifie de fournir une expérience utilisateur de premier ordre dans les applications localisées sur le Web d'aujourd'hui. Laissez entendre ce que vous pensez dans les commentaires ci-dessous, ou envoyez un tweet à ma façon.
Source link