Comment gérer l'internationalisation avec NextJS SSG

Emmanuel Gautier / March 14, 2021

3 min read

Générer statiquement un site avec le framework NextJS pour différentes langues n'est pas si simple. Le framework n'apporte pas un support claire pour ce type de cas d'usage et la documentation NextJS explique que le routing i18n n'est pas supporté pour le SSG.

Si vous êtes en train de voir le message i18n support is not compatible with next export, cet article devrait vous donner une solution de contournement.

Mettre en place le projet

Pour commencer, il nous faut créer un nouveau projet next avec le template with-react-intl

npx create-next-app -e with-react-intl

Si vous n'avez plus besoin de gérer des ressources traduites côté client, vous pouvez supprimer les lignes de la fonction getInitialProps et la partie pour la traduction dans la fonction render.

Le serveur pour le SSR est inutile si vous voulez seulement la partie SSG également. Vous vous supprimer la config tsconfig, le fichier server.ts et modifier votre package.json comme suivant :

  "scripts": {
    "dev": "next dev",
    "build": "npm run extract:i18n && npm run compile:i18n && next build",
    "export": "next export",
    "extract:i18n": "formatjs extract '{pages,components}/*.{js,ts,tsx}' --format simple --id-interpolation-pattern '[sha512:contenthash:base64:6]' --out-file lang/en.json",
    "compile:i18n": "formatjs compile-folder --ast --format simple lang compiled-lang",
    "start": "next start"
  },

Static Site Generation (aka SSG) avec NextJS

Quand vous génerez votre site statiquement, il n'est plus possible d'utiliser l'entête de la requête du navigateur ou toute autre information du navigateur pour savoir quelle langue utiliser.

Nous avons besoin d'introduire une nouvelle variable d'environnement NEXT_PUBLIC_LOCALE qui va contenir la locale du site géneré durant le process d'export.

Exemple de contenu dans un fichier .env.*

NEXT_PUBLIC_LOCALE=fr

Vous pouvez maintenant utiliser la variable NEXT_PUBLIC_LOCALE dans le fichier _app.tsx dans la fonction getInitialProps pour définir la langue.

const getInitialProps: typeof App.getInitialProps = async (appContext) => {
  const locale = appContext.router.locale || process.env.NEXT_PUBLIC_LOCALE
  const [supportedLocale, messagePromise] = getMessages(locale)

  const [, messages, appProps] = await Promise.all([
    polyfill(supportedLocale),
    messagePromise,
    App.getInitialProps(appContext),
  ])

  return {
    ...(appProps as any),
    locale: supportedLocale,
    messages: messages.default,
  }
}

Grâce à cette variable et le changement fait, react-intl va maintenant utiliser la langue contenue dans la variable d'environnement. Les messages traduits vont être pris à partir de la bonne langue.

Maintenant, vous avez un site disponible en plusieurs langues. Vous pouvez construire votre site sur plusieurs noms de domaine également avec une gestion de plusieurs pipeline de build. Vous pouvez réaliser ce type d'implémentation avec des services comme Netlify, Vercel, ... etc.

Exemple généré pour deux langues et déployé avec Vercel :

Si vous souhaitez en savoir plus, vous pouvez jeter un oeil au Code Source

Consulting

Si vous recherchez des solutions à un problème ou avez besoin de conseils, je suis là pour vous aider ! N'hésitez pas à réserver un call avec moi pour une session de consulting personnalisée. Discutons de votre situation et trouvons ensemble la meilleure solution à implémenter.

Partager cet article
Suivre le flux RSS

Inscrivez-vous à la Newsletter

Rejoignez nous en vous abonnant à ma newsletter !