Aller au contenu
1 septembre 202612 min readGuides

Gérer les fichiers de traduction sans éditer le JSON à la main

La gestion des fichiers de traduction (translation file management) est la pratique consistant à garder les fichiers à partir desquels une application charge ses traductions (JSON, YAML, .resx, .po, .strings et formats similaires) complets, valides et synchronisés avec le code qui les utilise, sans que les développeurs ou les traducteurs n'éditent ces fichiers à la main. Dans la plupart des configurations, les fichiers existent toujours. Ce qui change, c'est leur rôle : ils deviennent une sortie du workflow de traduction au lieu d'en être l'interface utilisateur.

Ce billet explique comment les équipes en viennent à éditer leurs fichiers de traduction à la main, ce qui casse quand elles le font, à quoi ressemblent vraiment les alternatives, et ce qu'un changement de workflow ne corrige pas.

Faits clés
  • Un fichier de traduction est une entrée de build, pas un document : une virgule finale ou un guillemet non échappé le rend invalide, et un fichier invalide échoue en général silencieusement à l'exécution.
  • L'édition manuelle passe mal à l'échelle sur deux axes à la fois : le nombre de langues et le nombre de personnes qui doivent changer du texte. Un développeur avec deux langues, ça va ; un traducteur dans une pull request, non.
  • Ce qui casse : des conflits de fusion sur les fichiers de langue, une dérive entre fichiers et code (clés manquantes et orphelines), des clés sans propriétaire, un déploiement pour chaque coquille, et une terminologie qui varie entre fichiers sans aucune vue transversale.
  • Ce qui supprime l'édition : des clés qui naissent dans le code (extraction ou signalement à l'exécution), un éditeur pour les personnes qui écrivent du texte, et des fichiers générés par une étape de synchronisation ou remplacés par une livraison via CDN. Les agents de code peuvent fournir des ébauches ; ils ne remplacent pas cette couche.

Pourquoi les équipes finissent par éditer leurs fichiers de traduction à la main

Personne ne choisit cela comme stratégie. Tout commence par la décision manifestement correcte : i18next, react-intl, vue-i18n et leurs semblables chargent un fichier JSON par langue, donc le premier développeur crée en/common.json, ajoute de/common.json et édite les deux dans son éditeur de code. Clés imbriquées ou plates, placeholders {{count}}, suffixes de pluriel _one et _other : avec une personne et deux langues, éditer le fichier est l'outil de traduction, et un bon.

Puis les utilisateurs de cet outil changent alors que l'outil reste. Une troisième langue arrive avec une collègue qui la parle. Un product manager veut corriger un libellé avant la démo. Une traductrice d'agence livre le polonais. Chacun d'eux reçoit exactement ce qu'avait le premier développeur : un fichier à la syntaxe stricte, sans contexte, avec un workflow git autour. La configuration n'a pas empiré. Les personnes qui l'utilisent ont cessé d'être des développeurs.

Le format lui-même ajoute des pièges invisibles jusqu'à ce qu'ils se déclenchent. JSON n'autorise ni virgule finale, ni guillemet simple, ni guillemet non échappé à l'intérieur des chaînes. Les formes de pluriel sont encodées comme des suffixes de clé qui diffèrent entre les conventions JSON v3 et v4 d'i18next (la référence du format JSON couvre les deux). Un placeholder renommé dans une langue s'affiche littéralement à l'écran. Et comme le fichier est chargé à l'exécution, une erreur de syntaxe ne fait pas échouer le build ; elle fait échouer la page, pour les utilisateurs de cette langue, après le déploiement.

Ce qui casse

Des conflits de fusion sur le fichier le plus ennuyeux du dépôt

Deux branches de fonctionnalité ajoutent chacune des clés à common.json. JSON n'a aucune sémantique de fusion : le conflit atterrit sur l'accolade fermante, quelqu'un le résout à la main, et les clés d'une des branches disparaissent en silence. Dans beaucoup de dépôts front-end, les fichiers de langue sont le type de fichier au taux de conflit le plus élevé, précisément parce que chaque fonctionnalité les touche et que personne ne s'en sent propriétaire.

Une dérive entre fichiers et code

Le code référence des clés qu'aucun fichier ne contient, et l'interface affiche le nom de la clé ou le texte anglais de repli. Les fichiers contiennent des clés que plus aucun code ne référence, et les traducteurs continuent de traduire des chaînes mortes. Le fichier anglais a été mis à jour, l'allemand non, et rien ne marque la valeur allemande comme périmée. En un an, les fichiers de langue divergent structurellement, et le seul moyen de s'en apercevoir est de les comparer à la main.

Des traducteurs dans git

Dès qu'un traducteur édite un fichier, le workflow exige une pull request. Le relecteur ne peut pas juger le polonais, alors il relit le diff pour la syntaxe. Le traducteur ne voit pas où la chaîne apparaît, ce que contiendra {{name}} ni si le bouton est assez large. En pratique, la correction voyage sous forme de message de chat qu'un développeur colle dans le fichier, ce qui est de l'édition manuelle avec une étape de plus.

Des clés sans propriétaire

Le nommage des clés se décide pull request par pull request. btn.save, actions.save et common.save coexistent et personne ne sait s'ils sont censés différer. Renommer une clé signifie toucher chaque fichier de langue. En supprimer une signifie espérer qu'aucun écran ne l'utilise encore. Le fichier n'a aucune notion de qui a créé une clé, quand, ni pourquoi.

Un déploiement pour chaque coquille

Dans une configuration basée sur des fichiers, un changement de traduction est un changement de code : commit, build, déploiement. Un libellé erroné en italien part avec le prochain train de livraison, à moins que quelqu'un ne fasse un hotfix en production pour une chaîne. Les équipes apprennent à regrouper les corrections de traduction, ce qui est une façon polie de les laisser cassées un moment.

La cohérence entre fichiers est invisible

Le même terme source est traduit de trois façons différentes selon les namespaces, et aucun outil au niveau fichier ne peut vous le montrer, parce que le désaccord vit entre les fichiers, pas dans l'un d'eux. C'est la classe de défauts la plus répandue dans les données réelles de traduction, et celle que la relecture manuelle détecte le moins bien ; les chiffres sont dans ce qui casse vraiment dans les traductions.

Comment les équipes gèrent leurs fichiers de traduction aujourd'hui

La plupart des équipes se trouvent dans l'une de cinq configurations, et le tableau honnête est que chacune d'elles convient à quelqu'un.

  • Un éditeur de code et des conventions. VS Code avec validation JSON et une extension comme i18n Ally qui montre l'état de traduction par langue. Fonctionne pour un développeur seul ou une petite équipe où tous ceux qui éditent du texte savent lire le format. Cesse de fonctionner le jour où un non-développeur doit changer une chaîne. Si vous en êtes là, la FAQ sur l'ouverture et l'édition des fichiers JSON est le guide pragmatique.
  • Des allers-retours par tableur. Exporter le fichier vers une feuille, l'envoyer aux traducteurs, réimporter le résultat avec un script. Familier pour les traducteurs, et un problème d'instantané pour tous les autres : la feuille et le fichier divergent pendant que la traduction est en cours, et la fusion au retour est de nouveau manuelle.
  • Des scripts et une synchronisation CI. Un outil extrait les clés du code source (pour i18next, i18next-cli extract), un script ou une GitHub Action les pousse vers un service et récupère les fichiers traduits, éventuellement avec une traduction automatique ou IA entre les deux. Cela garde les fichiers générés et les développeurs à distance. Il faut encore un éditeur de l'autre côté pour les humains qui relisent et corrigent, et cela ne répond pas de soi-même aux questions de propriété et de cohérence.
  • Un système de gestion de traduction. Les clés arrivent du code, les traducteurs travaillent dans un éditeur avec contexte et terminologie, les fichiers sont exportés ou synchronisés dans les formats attendus par le build, ou livrés via un CDN pour que le build n'en ait plus besoin. C'est la configuration vers laquelle les quatre autres évoluent dès que plus d'une personne écrit du texte.
  • Des agents de code qui éditent les fichiers. L'option la plus récente : un agent ajoute la clé aux douze fichiers de langue, rédige les traductions et ouvre la pull request. Il est vraiment bon pour la partie mécanique. Il réintroduit aussi le problème d'origine à plus grande vitesse : du texte que personne n'a relu, une terminologie qui varie entre exécutions, et aucune trace au-delà d'un commit signé par un bot. Ce qui échoue dans les pipelines 100 % IA, et le chemin pour en sortir, est décrit dans quand les traductions IA cassent.

Ce qui supprime vraiment l'édition manuelle

Quel que soit l'outil, quatre propriétés séparent un workflow où personne n'édite les fichiers de traduction d'un workflow où quelqu'un le fait encore.

  1. Les clés naissent dans le code, pas dans les fichiers. Soit une étape d'extraction statique lit les appels de traduction, soit l'application en cours d'exécution signale une clé la première fois qu'elle est utilisée. Dans les deux cas, un développeur n'ouvre jamais un fichier de langue pour y ajouter une entrée.
  2. Les personnes qui écrivent du texte ont un éditeur. Texte source, placeholders, captures d'écran, glossaire, historique de la clé, toutes les langues côte à côte. Un traducteur qui voit le bouton n'a pas besoin de deviner sa largeur.
  3. Les fichiers sont générés ou absents. Soit une étape de synchronisation ou de téléchargement écrit les fichiers dans le format attendu par le build, en préservant structure et formes de pluriel à l'aller-retour, soit l'application charge les traductions à l'exécution et le dépôt ne contient aucun fichier de langue. La synchronisation par différence compte ici : une pull request ne devrait traduire que les clés qu'elle a ajoutées, pas repousser tout le projet.
  4. Chaque changement a un propriétaire et une trace. Qui a ajouté la clé, qui l'a traduite, qui l'a approuvée, quand elle a été publiée. Un fichier n'a rien de tout cela ; une pull request en a une fraction.

Ce que cela ne résout pas

Supprimer l'édition de fichiers supprime une corvée. Cela ne supprime pas les vraies difficultés de la localisation, et un changement de workflow ne devrait pas être vendu comme s'il le faisait.

  • La stratégie de clés reste la vôtre. Clés en langage naturel ou identifiants stables, namespaces par fonctionnalité ou par page : un outil déplace les clés, il ne les conçoit pas. Les compromis sont dans le guide de nommage des clés i18n.
  • L'ambiguïté a toujours besoin d'un humain pour la remarquer. « Open » comme verbe et « Open » comme statut peuvent nécessiter deux traductions ; aucune étape de synchronisation ne le repère. Les fonctions de contexte et les captures d'écran aident le traducteur une fois que quelqu'un a signalé le cas.
  • La qualité est une couche à part. Une terminologie qui ne doit pas dériver, un registre qui ne doit pas basculer au milieu de l'application, et la question de qui a approuvé une traduction relèvent d'un glossaire, d'un workflow de relecture et de contrôles QA automatiques, pas de l'endroit où vivent les fichiers.
  • Parfois, le fichier est le bon outil. Un développeur, deux langues qu'il sait lire, aucun revenu qui dépende du texte : un éditeur de code est la configuration correcte la moins chère. Le signal pour changer, c'est la deuxième personne qui a besoin de modifier du texte.

Comment cela fonctionne dans Locize

Locize est construit autour des quatre propriétés ci-dessus, pour l'écosystème i18next d'abord, et pour les autres formats via la CLI.

  • Des clés depuis le code. Avec i18next-locize-backend et saveMissing: true (limité au développement, pour que la production reste en lecture seule), chaque clé que l'application affiche pour la première fois est créée dans le projet avec sa valeur par défaut ; locizify fait de même pour les sites statiques avec une seule balise script. Vous préférez un pipeline statique ? i18next-cli extract suivi de locize-sync, ou locize sync pour JSON, YAML, XLIFF, CSV, PO, RESX, Fluent, Properties et d'autres formats, comme décrit dans la documentation de la CLI.
  • Un éditeur pour tous ceux qui écrivent du texte. La vue CAT montre toutes les langues d'une clé côte à côte, avec des filtres pour les valeurs non traduites et à relire, des actions en masse, l'import et l'export dans les formats pris en charge, et un historique par clé qui enregistre qui a changé quoi et quand.
L'éditeur de traduction Locize : toutes les langues d'une clé côte à côte, avec filtres, actions en masse et assistant IA
L'éditeur de traduction Locize : toutes les langues d'une clé côte à côte, avec filtres, actions en masse et assistant IA
  • Des fichiers générés, ou aucun. locize download et les GitHub Actions écrivent les fichiers attendus par votre build ; locize sync --changed-only limite une pull request aux clés qu'elle a réellement modifiées (locize-cli 12.7 ou plus récent, i18next-cli 1.72 ou plus récent). Ou passez-vous des fichiers : les traductions sont publiées sur le CDN par défaut, et l'application les charge à l'exécution, si bien qu'une correction est en ligne sans commit ni redéploiement.
  • Des premières ébauches, sans fichier non plus. Les nouvelles clés dans la langue de référence sont traduites dans chaque langue cible par la traduction automatique, avec le glossaire et le guide de style du projet injectés dans la requête, et marquées à relire pour qu'une personne les confirme dans l'éditeur plutôt que dans un diff.

Le fichier JSON ne disparaît pas de votre vie ; il cesse d'être l'endroit où la traduction se fait. Pour voir la différence sur votre propre projet, créez un projet, importez les fichiers que vous avez aujourd'hui, et regardez la prochaine clé arriver depuis votre code plutôt que depuis votre clavier.

Questions fréquentes

Comment gérer les fichiers de traduction sans éditer le JSON à la main ? Faites des fichiers une sortie du workflow plutôt que son interface utilisateur. Les clés naissent dans le code, par extraction en CI ou par signalement à l'exécution comme l'option saveMissing d'i18next ; les traducteurs travaillent dans un éditeur avec le texte source, les placeholders et la terminologie sous les yeux ; les fichiers JSON, YAML ou resx sont générés par une étape de synchronisation ou de téléchargement, ou remplacés par une livraison via CDN.

Les traducteurs doivent-ils éditer les fichiers JSON directement ? Non. Un fichier de traduction est une entrée de build à la syntaxe stricte, et un fichier invalide échoue en général silencieusement à l'exécution. Les traducteurs ne voient pas non plus où apparaît une chaîne, ce que représente un placeholder ni comment le terme a été traduit ailleurs. Donnez-leur un éditeur et laissez le fichier être généré à partir de celui-ci.

Quelle est la différence entre l'extraction de clés et saveMissing ? L'extraction parcourt le code source à la recherche des appels de traduction et écrit les clés dans des fichiers, de façon déterministe et sans lancer l'application. saveMissing signale une clé manquante depuis l'application en cours d'exécution la première fois qu'elle est utilisée, avec sa valeur par défaut. Beaucoup d'équipes utilisent saveMissing en développement et l'extraction comme contrôle en CI.

Ai-je encore besoin de fichiers de traduction dans mon dépôt ? Seulement si votre build en a besoin. Avec une livraison via CDN, le dépôt ne contient aucun fichier de langue et une correction publiée dans l'éditeur est en ligne sans déploiement. Les équipes qui ont besoin de fichiers pour le rendu côté serveur ou des builds statiques les téléchargent en CI comme artefacts générés, jamais édités à la main.

Les agents de code IA peuvent-ils gérer mes fichiers de traduction ? Ils peuvent écrire et modifier les fichiers, ce qui supprime la saisie mais pas la dérive : du texte non relu, une terminologie qui varie entre exécutions, aucune trace de qui a approuvé quoi. Les agents fonctionnent le mieux comme contributeurs d'un workflow géré, en signalant les nouvelles clés et en rédigeant des ébauches, tandis que la cohérence, la relecture et l'historique vivent dans le système de gestion de traduction.

Fatigué de gérer vos traductions à la main ?

Locize est le backend de gestion de traductions créé par l'équipe i18next : diffusion CDN, traduction IA, édition in-context, sans redéploiement.

Démarrez votre essai gratuit de 14 jours