BookTranslator
BookTranslator

Comment traduire un fichier de langue JSON sans casser les clés ni les espaces réservés

Découvrez quelles valeurs d'un fichier en.json sont traduites, ce qu'un traducteur de fichiers réécrit (commentaires, ordre des clés, identifiants longs) et comment vérifier les espaces réservés, les pluriels ICU et les clés avec un script gratuit et un fichier de test.

BookTranslator

BookTranslator Team

14 min de lecture

Pour traduire un fichier de langue JSON tel que en.json, confiez le fichier entier à un traducteur qui comprend le JSON. Coller le texte brut dans une fenêtre de chat ou un traducteur web est la méthode risquée. Un traducteur compatible JSON lit le fichier, traduit uniquement les valeurs textuelles et réécrit les mêmes clés, de sorte que votre application puisse toujours charger le fichier. Le copier-coller peut traduire une clé, modifier un guillemet ou supprimer une accolade. Chacun de ces incidents casse le fichier.

Conserver les clés est la partie facile. L'essentiel des problèmes survient ensuite : un espace réservé {name} qui revient sous la forme {nom}, un pluriel ICU qui perd son cas other, une URL envoyée à la traduction comme n'importe quel autre texte, et quelques modifications que le traducteur apporte au fichier lui-même. C'est ce que ce guide aborde.

Nous avons créé un fichier de test contenant chacun de ces cas et écrit un vérificateur gratuit qui compare un fichier source avec sa traduction. Nous avons également exécuté le fichier de test à travers une copie locale du code d'analyse et d'écriture JSON utilisé par BookTranslator, avec un marqueur à la place d'un modèle, afin que vous puissiez voir exactement quelles valeurs sont envoyées et comment le fichier revient.

Réponse rapide : ce qui arrive à chaque partie du fichier

Partie du fichierExemple de notre testCe que fait BookTranslatorCe qu'il faut vérifier
Clés"greeting", "error"Conservées telles quellesRien
Valeurs en texte brut"Reading list"TraduitesSens, longueur à l'écran
Valeurs avec espaces réservés"Welcome back, {name}!", "Saved %s of %d chapters"Traduites, espaces réservés inclus dans le texte envoyéNoms et nombres d'espaces réservés (le vérificateur s'en charge)
Messages pluriels ICU"{count, plural, one {# book} other {# books}}"Envoyés comme une seule chaîneLe cas other, et les catégories de pluriel pour la langue cible
HTML en ligne"accept the <b>Terms</b>."Traduit ; le nombre de balises est vérifié après traductionNoms et nombres de balises (le vérificateur s'en charge)
URL stockées sous forme de texte"https://example.com/help"Envoyées pour traductionQu'elles sont revenues inchangées
Valeurs sans lettres"2.4.1", "—", ""Laissées telles quellesRien
Nombres, true/false, null20, trueLaissés tels quelsTrès grands ID (voir ci-dessous)
Tableaux de chaînes["Open", "Save", "Export as EPUB"]Traduits dans le fichier traduit ; laissés non traduits dans le fichier bilingueLe fichier bilingue, si vous l'utilisez
Commentaires (JSONC)// Shown on the home screenSupprimés. Si une valeur contient aussi //, le fichier peut ne pas se chargerSupprimez les commentaires avant le téléversement

Le reste de ce guide montre l'origine de chaque ligne et ce qu'il faut faire.

Étape 1 : Vérifiez le fichier source avant de le téléverser

Exécutez le vérificateur sur le fichier que vous prévoyez de traduire. Il nécessite Python 3 et rien d'autre :

python3 check_i18n_json.py en.json

Sur notre fichier de test, il a affiché :

WARN  limits.projectId: 9007199254740993 is above 2^53 and can change in a JavaScript round trip; store IDs as strings
WARN  error.network: a flat key with dots and a nested key resolve to the same dot path; tools that address strings by dot path can mix them up
INFO  (root): 3 keys look like integers; JavaScript sorts those first and in numeric order when it rewrites the object
INFO  source: 17 strings, 2 numbers

Les deux avertissements et la note sur les clés de type entier correspondent chacun à un changement que nous avons observé lorsque notre fichier de test est passé par le traducteur. Si votre fichier n'en reçoit aucun, vous pouvez passer à l'étape 3.

Le vérificateur refuse également un fichier qui n'est pas du JSON strict, par exemple avec des commentaires ou des virgules finales, car c'est le problème suivant.

Ce qui est revenu de notre fichier de test

Le test a été exécuté le 2 novembre 2026, sur la gestion actuelle du JSON dans le backend de BookTranslator. Au lieu d'appeler un modèle, le test a remplacé chaque valeur qui aurait été envoyée pour traduction par [ZH] suivi du texte original. Cela rend le résultat prévisible : tout ce qui est précédé de [ZH] a été envoyé, tout ce qui ne l'est pas ne l'a pas été. Les deux sorties sont publiées : le fichier traduit et le fichier bilingue.

Le fichier traduit

Chaque clé est revenue inchangée et le fichier était toujours analysable. Les valeurs contenant des lettres ont été envoyées, y compris {name}, %s, le message ICU, la balise <b> et l’URL d’aide. La chaîne de version "2.4.1", le tiret et la chaîne vide n’ont pas été envoyés, car ils ne contiennent aucune lettre. Les nombres et les booléens sont restés tels quels.

Quatre autres choses ont changé :

  1. Une chaîne s’est retrouvée dans la mauvaise clé. Dans notre test, notre fichier contenait une clé plate "error.network" avec le texte « Check your connection. » ainsi qu’une clé imbriquée "error": { "network": "Network error" }. Le traducteur identifie chaque chaîne par son chemin avec des points entre les parties, donc les deux chaînes avaient la même adresse, error.network. Dans la sortie, les deux clés contenaient la traduction de « Network error ». « Check your connection. » avait disparu. Cela nécessite les deux styles dans le même fichier, ce qui est rare, mais l’échec est silencieux. Le vérificateur vous en avertit avant l’envoi.
  2. Les clés de type entier ont été réordonnées. "steps": { "10": ..., "2": ..., "1": ... } est revenu sous la forme "1", "2", "10". JavaScript liste toujours les clés de type entier en premier, par ordre numérique, lorsqu’il reconstruit un objet. Les clés et les valeurs correspondent toujours, donc votre application fonctionne, mais un diff par rapport au fichier source sera bruyant.
  3. Un grand ID a perdu en précision. 9007199254740993 est revenu sous la forme 9007199254740992. JavaScript stocke les nombres en virgule flottante 64 bits, et les entiers supérieurs à 2^53 ne peuvent pas tous être représentés exactement (MDN sur Number.MAX_SAFE_INTEGER). Stockez les ID longs sous forme de chaînes, ou gardez-les hors du fichier de langue.
  4. Le formatage a été réécrit. La sortie utilise une indentation de deux espaces et se termine par un saut de ligne. Si votre source utilisait des tabulations ou quatre espaces, attendez-vous à des changements d’espaces dans le diff.

Notre fichier de test ne contenait pas de clés en double, mais cela vaut la peine de le savoir : l’analyseur JSON de JavaScript ne conserve que la dernière valeur pour une clé répétée, donc le texte précédent n’est jamais traduit. Votre application chargerait la même dernière valeur, donc rien de visible ne casse, mais le vérificateur liste les clés en double pour que vous puissiez les nettoyer.

Le fichier bilingue

Le fichier bilingue conserve chaque valeur d’origine et ajoute une clé sœur avec _translated à la fin :

"greeting": "Welcome back, {name}!",
"greeting_translated": "[ZH] Welcome back, {name}!",

Cela fonctionne bien pour la relecture, car la source et la traduction sont côte à côte. Ce n’est pas un fichier que votre application peut charger, car chaque clé a maintenant un jumeau. Utilisez le fichier traduit dans votre application.

Une lacune : les chaînes à l’intérieur de tableaux n’ont pas de clé sœur _translated, car les éléments de tableau n’ont pas de clé à laquelle en ajouter une. Dans notre test, "menu": ["Open", "Save", "Export as EPUB"] est revenu en anglais dans le fichier bilingue, mais traduit dans le fichier traduit. Si vous relisez à partir du fichier bilingue, vérifiez les tableaux dans le fichier traduit.

Fichiers avec commentaires

De nombreux projets conservent des commentaires dans leurs fichiers de langue (JSONC), ce que le JSON strict n’autorise pas. Le traducteur essaie d’abord le JSON strict. Si cela échoue, il supprime les commentaires et les virgules finales et réessaie. Supprimer les commentaires signifie supprimer tout ce qui suit // sur une ligne, et cela inclut le // dans https://.

Notre fichier avec un commentaire et une URL ne s’est pas chargé du tout ; l’analyse a échoué au premier commentaire. Un fichier avec des commentaires mais sans // à l’intérieur d’une valeur s’est chargé correctement, et les commentaires ont été supprimés de la sortie.

Donc : si votre fichier contient des commentaires, supprimez-les avant de l’envoyer, ou gardez une copie avec les commentaires et acceptez que la traduction ne les contienne pas.

Étape 2 : Préparer le fichier

Vous pouvez corriger la plupart de ces problèmes avant de traduire :

  • Rendez-le JSON strict. Supprimez les commentaires et les virgules finales. Si votre outil de build lit le JSONC, gardez le fichier commenté comme source et exportez une copie propre pour la traduction.
  • Utilisez un seul style de clé. Soit imbriquez les clés, soit aplatissez-les avec des points, pas les deux dans un même fichier. Si vous utilisez i18next, son option keySeparator contrôle la façon dont les points dans les clés sont lus, donc vérifiez ce paramètre avant d’aplatir quoi que ce soit.
  • Sortez les données non textuelles. Les ID, les URL, les indicateurs de fonctionnalité et les limites appartiennent à la configuration, pas au fichier de langue. Si une URL doit rester, gardez-la, mais attendez-vous à la vérifier après traduction. Notre guide sur ce qu’il ne faut pas traduire explique comment décider ce qui doit rester dans la langue d’origine.
  • Écrivez les espaces réservés de la même manière partout. Un seul style, comme {name}, est plus facile à vérifier qu’un mélange de {name}, {{name}} et %s.

Étape 3 : Traduire le fichier entier

Envoyez le fichier nettoyé au traducteur de documents de BookTranslator, qui liste .json avec les autres formats de localisation et de texte structuré qu’il accepte. Le prix est affiché avant le paiement. Une fois la tâche terminée, votre page d’historique propose le fichier traduit et le fichier bilingue en téléchargements séparés.

Deux aspects de la façon dont le texte est traduit influencent le résultat :

  • Le modèle ne voit pas vos clés. Chaque valeur est envoyée comme un segment numéroté, sans le nom de la clé. Si "button.open" et "status.open" contiennent tous deux « Open », le modèle n'a aucun moyen de savoir que l'un est un verbe et l'autre un adjectif. Les chaînes courtes et ambiguës sont celles à vérifier manuellement.
  • Chaque valeur est traduite indépendamment. Rien ne relie deux clés entre elles, donc le même mot à deux endroits peut revenir de deux façons différentes, et un mot qui nécessite deux traductions différentes peut revenir identique. Le glossaire automatique optionnel de BookTranslator collecte les noms, les lieux et les termes spécialisés et les maintient cohérents, mais vous ne pouvez pas lui fournir vos propres traductions fixes. Pour les termes qui doivent être traduits d'une manière exacte, tenez une liste de termes et vérifiez ces chaînes après traduction ; notre guide des glossaires explique comment en planifier un.

Les balises HTML en ligne sont comptées après traduction, et un segment dont les balises ne correspondent pas est réessayé. Les espaces réservés entre accolades, les espaces réservés de style %s et la syntaxe ICU sont envoyés avec le texte mais ne sont pas vérifiés de la même manière. Exécutez l'étape 4 sur chaque traduction.

Si vous préférez traduire avec un modèle de chat ou un modèle local, n'envoyez que les valeurs, jamais le fichier brut, et réinsérez-les par clé à l'aide d'un script. Les vérifications ci-dessous s'appliquent dans les deux cas.

Étape 4 : Vérifier le fichier traduit

Comparez la traduction avec la source :

python3 check_i18n_json.py en.json fr.json

Pour montrer ce qu'il détecte, nous avons créé un fichier français avec des erreurs plantées. Il est fait à la main, pas généré par un modèle. Après les mêmes avertissements de source qu'à l'étape 1, le vérificateur a affiché :

ERROR app.greeting: placeholders differ; lost ['name'] extra ['nom']
ERROR app.help_url: urls differ; lost ['https://example.com/help'] extra ['https://example.com/aide']
ERROR app.items: ICU message has no 'other' case
ERROR app.legacy: placeholders differ; lost ['%d'] extra []
ERROR limits.maxFiles: type changed from int to str
ERROR limits.projectId: non-text value changed: 9007199254740993 -> 9007199254740992
INFO  menu[1]: identical to source: 'Save'
INFO  compared 20 source values, 1 unchanged strings

Chacun de ces éléments apparaîtrait comme un bug dans l'application : un nom vide, un lien cassé, un plantage ou un message brut lors du rendu du pluriel, un nombre de chapitres manquant, une limite comparée comme du texte. La ligne INFO liste les chaînes revenues inchangées. Certaines sont correctes, comme les noms de marque ; « Save » dans un menu français ne l'est pas.

Le vérificateur compare les clés, les types de valeurs, les valeurs non textuelles, les espaces réservés ({name}, {{name}}, %s, %1$s, %@), les noms d'arguments ICU, les balises HTML et les URL. Il ne juge pas la traduction elle-même.

Les cas de pluriel sont censés changer

Un pluriel ICU liste un message par catégorie de pluriel. L'anglais a deux catégories, one et other, mais de nombreuses langues en ont un ensemble différent. Une bonne traduction russe de notre message items utiliserait normalement one, few, many et other, et une traduction japonaise seulement other. Ainsi, une discordance ici n'est pas toujours une erreur.

Les catégories proviennent des règles de pluriel CLDR d'Unicode, et other est celle que toutes les langues possèdent. Voici les catégories cardinales rapportées par Intl.PluralRules dans Node.js avec CLDR 48 :

LangueCatégories de pluriel
Anglais, allemandone, other
Français, espagnol, portugaisone, many, other
Russe, polonaisone, few, many, other
Arabezero, one, two, few, many, other
Japonais, chinois, coréenautre

Le français, l'espagnol et le portugais n'utilisent many que pour de très grands nombres ronds, comme un million, donc un message pour de petits nombres peut généralement s'en passer. Le vérificateur signale un other manquant comme une erreur, et tout autre changement de catégories comme un avertissement à comparer avec ce tableau. Vous pouvez afficher la liste pour n'importe quelle langue vous-même :

node -e 'console.log(new Intl.PluralRules("ru").resolvedOptions().pluralCategories)'

Le traducteur reçoit les cas anglais, alors vérifiez ce qui est revenu. Si un message en russe ou en arabe ne contient encore que one et other, ajoutez les cas manquants à la main, ou faites-le faire par un traducteur.

Chargez-le ensuite dans l'application

Le vérificateur prouve que le fichier peut être chargé sans risque, pas qu'il se lit bien. Passez l'application dans la nouvelle langue et examinez les écrans : les mots longs en allemand ou en finnois qui débordent d'un bouton, le texte de droite à gauche en arabe ou en hébreu, et les dates ou nombres que votre code formate séparément du fichier de langue. Notre guide sur la traduction et la localisation couvre ce qui change d'un marché à l'autre en dehors des mots.

Problèmes courants

Le fichier traduit ne se charge pas dans mon application. Lancez le vérificateur dessus. Si le vérificateur ne peut pas l'analyser, le fichier a été modifié après la traduction ou n'était pas valide au départ. S'il s'analyse, cherchez les lignes ERROR concernant les clés ou les types.

Une chaîne s'affiche comme un message ICU brut, du type {count, plural, ...}. La syntaxe ICU a été cassée lors de la traduction, généralement une accolade manquante ou un cas other absent. Copiez la structure depuis la source et traduisez uniquement les mots à l'intérieur de chaque cas.

Mon fichier est en YAML, en .po ou en Markdown. BookTranslator accepte aussi ces formats, mais chacun a ses propres règles. Pour la documentation, consultez notre guide de traduction Markdown ; pour les pages web, le guide des fichiers HTML.

Puis-je traduire uniquement les nouvelles clés ? Pas au sein d'un même envoi ; le fichier entier est traduit. Placez les nouvelles clés dans un fichier séparé, traduisez-le, puis fusionnez le résultat par clé. Le vérificateur confirmera que le fichier fusionné contient bien toutes les clés.

Dois-je traduire les clés ? Non. Les clés sont des identifiants que votre code recherche. Seules les valeurs sont du texte destiné à la lecture humaine.

Articles connexes