---
title: "verbatra diff"
description: "Affiche les clés qu'une exécution ajouterait ou retraduirait par locale et celles devenues orphelines, sans écrire de fichiers ni appeler de fournisseur."
type: "reference"
---
# verbatra diff

Affiche les clés qu'une exécution ajouterait ou retraduirait par locale et celles devenues orphelines, sans écrire de fichiers ni appeler de fournisseur.

Liste, par locale cible, les clés exactes en attente : celles qu'une exécution ajouterait, celles qu'elle retraduirait et celles désormais orphelines. `diff` fait la même lecture et la même comparaison que [`verbatra translate`](https://verbatra.kreitz-webdev.de/fr/docs/cli/translate.md), puis s'arrête : aucun appel de fournisseur, aucun fichier écrit, aucune mise à jour du [fichier de verrouillage](https://verbatra.kreitz-webdev.de/fr/docs/the-lock-file.md), aucune clé d'API requise.

## Synopsis [#synopsis]

```bash
verbatra diff [flags]
```

## Exemples [#exemples]

```bash
# liste les clés en attente par locale (sortie 1 s'il y en a)
verbatra diff

# seulement les locales allemande et française
verbatra diff --locales de,fr

# listes de clés lisibles par une machine pour un outil ou un commentaire de PR
verbatra diff --json

# liste aussi les clés source que ton code ne nomme plus
verbatra diff --unused
```

## Options [#options]

| Option | Argument | Défaut | Effet |
| --- | --- | --- | --- |
| `--locales` | `<list>` | toutes les cibles configurées | compare seulement ce sous-ensemble séparé par des virgules ; une locale non configurée échoue avec `UNKNOWN_LOCALE` et une liste vide avec `INVALID_LOCALES`, les deux avec la sortie `2` |
| `--unused` | aucun | désactivé | liste aussi les clés de la locale source qu'aucun appel sous les [racines de `extract`](https://verbatra.kreitz-webdev.de/fr/docs/config-file.md#extract) ne nomme ; voir [Clés source inutilisées](#clés-source-inutilisées) |

Accepte aussi les [options globales](https://verbatra.kreitz-webdev.de/fr/docs/cli.md#options-globales) `--cwd`, `--config` et `--json`.

## Comportement [#comportement]

### Clés en attente et orphelines [#clés-en-attente-et-orphelines]

Chaque locale liste quatre sortes de clés :

| Liste | Signification |
| --- | --- |
| `missing` (affichée comme `add`) | dans la source, absente de la cible : une exécution l'ajouterait |
| `changed` (affichée comme `re-translate`) | le texte source a changé depuis la dernière traduction : une exécution la retraduirait |
| `orphaned` | dans la cible, disparue de la source : seulement signalée |
| `emptySource` (affichée comme `empty source`) | la valeur source est vide ou ne contient que des espaces : rien à traduire tant que tu ne l'as pas écrite, jamais en attente |

Une locale a des changements en attente dès qu'elle a au moins une clé manquante ou modifiée. Les clés orphelines ne comptent jamais comme en attente, car une exécution par défaut les laisse en place ; seul [`verbatra translate --prune`](https://verbatra.kreitz-webdev.de/fr/docs/cli/translate.md) les supprime. [`verbatra check`](https://verbatra.kreitz-webdev.de/fr/docs/cli/check.md) donne les décomptes, `diff` donne les listes de clés.

### Clés source inutilisées [#clés-source-inutilisées]

<AvailableFrom version="0.11.0" />

`--unused` répond à une autre question que `orphaned` : quelles clés de ton fichier de locale source ton application ne nomme-t-elle plus ? Il analyse les `roots` du [bloc `extract`](https://verbatra.kreitz-webdev.de/fr/docs/config-file.md#extract) avec le lecteur de [`verbatra extract`](https://verbatra.kreitz-webdev.de/fr/docs/cli/extract.md) et liste chaque clé source qu'aucune référence statique ne nomme. Les deux listes ne sont jamais fusionnées. L'analyse ne fait que lire : rien n'est supprimé, et aucune clé d'API n'est lue. Supprimer une clé, c'est ta décision.

L'analyse modélise le runtime i18next. Ceci compte comme une référence :

- un appel `t(...)`, `$t(...)` ou `<object>.t(...)` n'importe où sous les racines, aussi via un alias comme `const { t: translate } = useTranslation()`, `const tr = i18n.t`, `t.bind(i18n)` ou `i18n.getFixedT(...)` ;
- un `keyPrefix` statique ou un troisième argument statique de `getFixedT`, qui couvre aussi la forme préfixée de chaque clé statique de ce fichier, et un `i18nKey` statique sur `Trans` ou dans un objet ;
- une clé avec namespace (`common:nav.home` couvre aussi `nav.home`), une clé en langage naturel et chaque entrée d'un tableau statique de clés ;
- une variante de pluriel ou de contexte d'une clé référencée (`t("items", { count })` couvre `items_one` et `items_other`) et chaque clé sous un parent référencé.

Les clés sont comparées dans l'encodage propre au format du catalogue, donc une clé JSON plate avec des points, un pluriel ou une entrée `msgctxt` gettext et une entrée `<plurals>` Android correspondent toutes à la clé que ton code nomme. Un template literal à tête statique, comme `` t(`nav.${page}`) ``, liste les clés sous `nav.` comme `possiblyDynamic`, à part de `unused`, et ne fait jamais échouer l'exécution.

Le rapport porte un `status` : `complete` (chaque clé atteignable a été bornée, donc `unused` est fiable), `unreliable` (une clé listée peut encore servir ; `unreliableBecause` nomme chaque raison avec son nombre et ses emplacements) ou `not-run` (rien n'est listé ; `reason` dit pourquoi) :

| Raison | `status` | Quand |
| --- | --- | --- |
| `dynamic-keys` | `unreliable` | une clé sans partie statique : `t(key)`, un template literal sans tête statique ou une concaténation |
| `dynamic-key-prefix` | `unreliable` | un préfixe `keyPrefix` ou `getFixedT` qui n'est pas une chaîne statique |
| `trans-without-key` | `unreliable` | un élément `Trans` sans `i18nKey` statique |
| `aliased-translate-function` | `unreliable` | `t` affectée à autre chose qu'une simple variable, comme `this.tr = t` |
| `translate-function-escapes` | `unreliable` | une fonction de traduction utilisée ailleurs que dans un appel direct, sa propre liaison, un alias local, `t={t}` sur `Trans` ou `Translation` ou un tableau de dépendances de hook : `renderRow(t)`, `{ t }`, `return t`, `export default t` |
| `unrecognised-translate-source` | `unreliable` | un `t` ou `$t` venant d'une source que l'analyse ne modélise pas, comme un hook enveloppe qui renvoie `useTranslation(...)`, des options de hook avec spread ou un résultat `getFixedT` exporté |
| `template-files-not-scanned` | `unreliable` | des fichiers `.vue`, `.svelte`, `.html`, `.htm`, `.astro`, `.hbs`, `.handlebars`, `.ejs`, `.pug`, `.njk`, `.liquid` ou `.mdx` sous les racines (les 20 premiers sont listés, tous sont comptés) |
| `incomplete-scan` | `unreliable` | un fichier trop gros, illisible ou pas lisible jusqu'au bout (aussi un élément JSX jamais fermé ou une chaîne qui court jusqu'à la fin de sa ligne), ou un répertoire impossible à lister |
| `EXTRACT_NOT_CONFIGURED` | `not-run` | aucun bloc `extract` |
| `EXTRACT_FS_UNSUPPORTED` | `not-run` | le système de fichiers d'un appelant du SDK ne sait pas lister les répertoires |
| `FRAMEWORK_NOT_MODELED` | `not-run` | le format est `next-intl-json`, `vue-i18n-json` ou `ngx-translate-json`, dont l'analyse ne modélise pas le runtime |
| `NO_SOURCE_FILES` | `not-run` | aucun fichier source sous les racines |
| `NO_REFERENCES_FOUND` | `not-run` | les fichiers analysés ne nomment aucune clé et n'ont aucun site de clé dynamique alors que le catalogue n'est pas vide, ce qui veut souvent dire que les racines ratent ton code |

Les sources de fonctions de traduction reconnues sont : `useTranslation(...)` déstructuré dans une liaison locale non exportée avec des arguments statiques ; un `i18n.getFixedT(...)` local avec des arguments statiques ; un appel direct sur un membre `t` (`i18n.t("key")`, `this.props.t("key")`) et son alias local ; `<Translation>{(t) => ...}</Translation>` ; `withTranslation("ns")(Component)` avec `props.t(...)` ; et `import { t } from "i18next"`. Toute variable ou tout membre nommé `t` ou `$t` est jugé, donc un `frame.t + 1` sans rapport peut rendre le rapport non fiable. Dans les fichiers `.tsx`, `.jsx` et `.js`, le texte JSX et les valeurs d'attribut entre guillemets sont lus comme du balisage, jamais comme du code.

Chaque clé listée montre sa forme décodée (une entrée `msgctxt` gettext comme `menu|Open`) ; `--json` porte aussi la `catalogKey` telle que l'adaptateur l'écrit. Une clé utilisée seulement hors du code analysé (un template serveur, un CMS) va dans [`extract.unused.ignore`](https://verbatra.kreitz-webdev.de/fr/docs/config-file.md#extract) : un motif correspond à la clé décodée, et une clé qui correspond est listée sous `ignored`, jamais écartée en silence.

### Clés protégées [#clés-protégées]

<AvailableFrom version="0.12.0" />

Les clés manquantes et modifiées que `translate` laisserait à une personne (une personne a écrit, importé ou modifié la valeur hors de verbatra, ou la clé correspond à `pinnedKeys`) sont listées en plus sous `protected` ; voir [Protéger les traductions humaines](https://verbatra.kreitz-webdev.de/fr/docs/protecting-human-translations.md). Elles restent sous `add` et `re-translate`, puisqu'elles sont toujours en attente. Si `verbatra.provenance.json` est corrompu ou vient d'un verbatra plus récent, seules les clés épinglées sont listées.

### Sortie JSON [#sortie-json]

Schéma : [`diff-envelope.json`](https://verbatra.kreitz-webdev.de/schema/v1/diff-envelope.json) valide l'enveloppe entière ; [Schémas](https://verbatra.kreitz-webdev.de/fr/docs/cli/output.md#schémas) liste les autres.

`--json` affiche une [enveloppe](https://verbatra.kreitz-webdev.de/fr/docs/cli/output.md#sortie-json) dont le `result` est un `DiffSummary`. `hasPendingChanges` est vrai exactement quand la commande sort avec `1` pour des clés en attente :

```ts
interface DiffSummary {
  hasPendingChanges: boolean;
  locales: LocaleDiff[];
  unused?: UnusedKeysReport;   // seulement avec --unused
}

interface LocaleDiff {
  locale: string;
  missing: string[];           // serait ajoutée
  changed: string[];           // serait retraduite
  orphaned: string[];          // seulement signalée
  emptySource?: string[];      // valeur source vide : jamais en attente
  hasPendingChanges: boolean;  // missing.length > 0 || changed.length > 0
  changedOrigins?: Record<string, KeyOrigin>; // absent si le fichier de provenance est illisible
  protected?: string[];        // clés en attente que translate laisse intactes
}
```

### Retour dans le terminal [#retour-dans-le-terminal]

<AvailableFrom version="0.12.0" />

`diff` affiche une ligne pendant qu'il travaille (avec un décompte des fichiers quand `--unused` analyse le code) et suggère la commande suivante :

```text output
verbatra: diffing and scanning the source... done (0.8s)
next: verbatra translate (send the pending keys to your provider)
```

Quand toutes les clés en attente sont protégées, il suggère plutôt `verbatra studio` ; avec `provider: { id: "none" }`, il suggère `verbatra export`. Ces lignes vont sur stderr, et `--quiet` les supprime. Consulte [Sortie dans le terminal](https://verbatra.kreitz-webdev.de/fr/docs/cli/output.md#sortie-dans-le-terminal).

## Codes de sortie [#codes-de-sortie]

| Code | Signification |
| --- | --- |
| `0` | aucune locale n'a de clé à ajouter ou à retraduire, et aucune analyse complète avec `--unused` n'a trouvé de clé inutilisée |
| `1` | au moins une locale a une clé manquante ou modifiée, ou une analyse `complete` avec `--unused` a trouvé une clé inutilisée |
| `2` | impossible de s'exécuter : une erreur globale, une valeur `--locales` non configurée (`UNKNOWN_LOCALE`) ou une erreur d'utilisation, comme une liste `--locales` vide (`INVALID_LOCALES`) |

Les clés orphelines, possiblement dynamiques et ignorées, ainsi qu'un rapport `unreliable` ou `not-run`, ne produisent jamais `1` à eux seuls. Consulte [le contrat des codes de sortie](https://verbatra.kreitz-webdev.de/fr/docs/cli/output.md#codes-de-sortie).

## Voir aussi [#voir-aussi]

- [`verbatra check`](https://verbatra.kreitz-webdev.de/fr/docs/cli/check.md) donne les décomptes par locale derrière ces listes.
- [`verbatra translate`](https://verbatra.kreitz-webdev.de/fr/docs/cli/translate.md) applique les changements en attente ; `--prune` supprime les clés orphelines.
- [Le fichier de configuration](https://verbatra.kreitz-webdev.de/fr/docs/config-file.md#extract) documente le bloc `extract` et `unused.ignore`.
- [CI et codes de sortie](https://verbatra.kreitz-webdev.de/fr/docs/ci-and-exit-codes.md) montre `diff` dans un pipeline.
