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.

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 fichier | Exemple de notre test | Ce que fait BookTranslator | Ce qu'il faut vérifier |
|---|---|---|---|
| Clés | "greeting", "error" | Conservées telles quelles | Rien |
| Valeurs en texte brut | "Reading list" | Traduites | Sens, 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îne | Le 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 traduction | Noms et nombres de balises (le vérificateur s'en charge) |
| URL stockées sous forme de texte | "https://example.com/help" | Envoyées pour traduction | Qu'elles sont revenues inchangées |
| Valeurs sans lettres | "2.4.1", "—", "" | Laissées telles quelles | Rien |
Nombres, true/false, null | 20, true | Laissés tels quels | Trè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 bilingue | Le fichier bilingue, si vous l'utilisez |
| Commentaires (JSONC) | // Shown on the home screen | Supprimés. Si une valeur contient aussi //, le fichier peut ne pas se charger | Supprimez 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é :
- 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. - 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. - Un grand ID a perdu en précision.
9007199254740993est revenu sous la forme9007199254740992. 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 surNumber.MAX_SAFE_INTEGER). Stockez les ID longs sous forme de chaînes, ou gardez-les hors du fichier de langue. - 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
keySeparatorcontrô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 :
| Langue | Catégories de pluriel |
|---|---|
| Anglais, allemand | one, other |
| Français, espagnol, portugais | one, many, other |
| Russe, polonais | one, few, many, other |
| Arabe | zero, one, two, few, many, other |
| Japonais, chinois, coréen | autre |
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





