Retour

Vous faites l’i18n Next.js de la mauvaise façon

General Translation avatarGeneral Translation
Ernest McCarter avatarErnest McCarter
guideinternationalizationnextjsi18ngt-nextapp-routertutorial

L’internationalisation en JavaScript a convergé vers une convention bancale : extraire chaque chaîne visible par l’utilisateur dans un fichier JSON, lui attribuer une clé, puis référencer cette clé dans vos composants. t('home.hero.title') au lieu du texte lui‑même. Votre UI vit à un endroit, votre contenu à un autre.

Ça marche. Des milliers d’applications sont mises en production de cette façon. Mais l’expérience développeur n’est pas excellente.

Lire t('checkout.summary.total') lors d’une revue de code ne vous dit rien — vous devez ouvrir un fichier JSON pour voir ce qui a changé. Il faut inventer les clés, les structurer en espaces de noms, et les garder synchronisées. Des traductions obsolètes s’accumulent parce que personne ne sait vraiment quelles clés sont encore utilisées. Le problème est suffisamment répandu pour qu’il existe des catégories entières d’outils dédiés à le gérer : des extensions d’IDE qui suggèrent automatiquement des clés, des générateurs de types qui les valident, des linters qui signalent celles qui ne sont plus utilisées. Ces outils résolvent un problème créé par un paradigme mal conçu.

Le composant <T>

Le contenu ne devrait pas être séparé de l’endroit où il est utilisé. Un composant qui affiche un titre, un paragraphe et un bouton devrait être l’unique source de vérité pour ce que ces éléments affichent — pas un proxy qui pointe vers des chaînes stockées ailleurs. Quand votre code et vos traductions sont deux systèmes parallèles, ils finissent par diverger. Inévitablement.

Et si la bibliothèque fonctionnait dans l’autre sens — en s’adaptant à votre code plutôt qu’en vous demandant de le restructurer ? Voici à quoi i18n devrait ressembler.

import { T } from 'gt-next';

function Hero() {
  return (
    <T>
      <h1>Ship your product worldwide</h1>
      <p>Reach every market without rewriting your app.</p>
    </T>
  );
}

Entourez votre JSX avec <T>. Le texte anglais reste exactement là où vous l’avez écrit. Quand un utilisateur visite le site en espagnol ou en japonais, le contenu à l’intérieur de <T> est traduit — structure, mise en forme, tout compris.

Pas de clés. Pas de fichiers JSON. Pas de références croisées. Votre code est la source de vérité.

Configuration

La syntaxe ci‑dessus provient de gt-next, une bibliothèque i18n open source pour Next.js App Router. Pour commencer, il suffit d’exécuter une seule commande :

npx gtx-cli@latest init

L’assistant de configuration installe les dépendances, encapsule votre configuration Next.js avec withGTConfig, ajoute GTProvider à votre layout racine, crée un gt.config.json avec vos locales, configure des clés d’API de développement pour le rechargement à chaud des traductions et configure le stockage des traductions sur un réseau de diffusion de contenu (CDN) — le tout de manière interactive.

Une fois cela fait, encapsulez le contenu dans <T>, lancez votre serveur de développement et utilisez le composant <LocaleSelector> pour basculer entre les langues :

import { LocaleSelector } from 'gt-next';

function Header() {
  return (
    <header>
      <nav>{/* ... */}</nav>
      <LocaleSelector />
    </header>
  );
}

Les traductions sont générées à la demande en environnement de développement, ce qui vous permet d’afficher immédiatement votre application dans n’importe quelle langue.

Déploiement

En production, les traductions sont pré‑générées.

  1. Obtenez une clé d’API de production sur dash.generaltranslation.com. Les clés de production commencent par gtx-api- (différentes des clés gtx-dev- utilisées en local).

  2. Ajoutez l’étape de traduction à votre build :

{
  "scripts": {
    "build": "npx gtx-cli translate --publish && next build"
  }
}

La commande translate analyse l’ensemble de votre code pour toutes les utilisations de <T>, génère les traductions et les publie sur un CDN (Content Delivery Network, réseau de diffusion de contenu). Au moment du build de votre application, toutes les locales sont prêtes.

Prochaines étapes