Skip to main content

Sincronizzazione dei file di traduzione: mantenere allineate le chiavi i18n tra le lingue

Ogni volta che uno sviluppatore aggiunge una chiave alla lingua di origine, altri 15 file perdono la sincronizzazione. Le chiavi mancanti mostrano agli utenti percorsi non elaborati. Le chiavi obsolete sprecano il tempo dei traduttori e aumentano le dimensioni del bundle. La sincronizzazione automatizzata mantiene tutto allineato.

1

Il problema della sincronizzazione

I file di traduzione divergono continuamente. Uno sviluppatore aggiunge 'settings.notifications.title' a en.json, ma dimentica di inserirlo negli altri 15 file di lingua. Un altro rimuove 'onboarding.welcome' dal codice, lasciandolo però in tutti i file. Un terzo rinomina 'user.name' in 'user.displayName' in inglese, ma non nelle altre lingue. Nel corso dei mesi, i file divergono: le chiavi risultano mancanti, obsolete o non corrispondenti tra le lingue.

The drift problem
// The problem: translation files drift out of sync

// Developer adds a new feature with new keys:
// en.json (source of truth)
{
  "nav.home": "Home",
  "nav.about": "About",
  "nav.pricing": "Pricing",     // NEW
  "nav.changelog": "Changelog"  // NEW
}

// de.json (out of sync - missing new keys)
{
  "nav.home": "Startseite",
  "nav.about": "Über uns"
  // nav.pricing - MISSING
  // nav.changelog - MISSING
}

// de.json also has stale keys from deleted features:
{
  "nav.home": "Startseite",
  "nav.about": "Über uns",
  "nav.legacy_page": "Alte Seite"  // STALE - removed from en.json
}
Le chiavi mancanti sono peggiori delle traduzioni mancanti. Una traduzione mancante può passare alla lingua di origine. Una chiave mancante causa un errore durante l'esecuzione, mostra un percorso non elaborato all'utente oppure visualizza una stringa vuota. La sincronizzazione deve essere imposta, non lasciata al caso.
2

Rilevamento delle chiavi mancanti

Una chiave mancante esiste nella lingua di origine, ma non in quella di destinazione. È il problema di sincronizzazione più comune e più dannoso: gli utenti vedono percorsi non elaborati come 'settings.notifications.title' anziché testo tradotto. i18n-validate rileva le chiavi mancanti confrontando la struttura di ogni lingua con quella di origine.

Terminal
# Detect missing and stale keys
npx i18n-validate sync \
  --source locales/en.json \
  --targets 'locales/*.json'

# Output:
# locales/de.json:
#   Missing keys (2):
#     - nav.pricing
#     - nav.changelog
#   Stale keys (1):
#     - nav.legacy_page
#   Coverage: 66.7% (2/3 keys)
#
# locales/ja.json:
#   Missing keys (5):
#     - nav.pricing
#     - nav.changelog
#     - settings.theme
#     - settings.language
#     - settings.notifications
#   Coverage: 50.0% (5/10 keys)
Esegua i18n-validate con il flag --check missing-keys per concentrarsi sui problemi di sincronizzazione. Usi --severity error affinché le chiavi mancanti causino il fallimento della CI e vengano corrette prima del merge.
3

Rilevamento delle chiavi obsolete

Una chiave obsoleta esiste nei file di traduzione, ma non viene più richiamata nel codice. Le chiavi obsolete sprecano il tempo dei traduttori, che traducono stringhe mai viste, aumentano le dimensioni del bundle e rendono confusa la manutenzione. Per rilevarle, è necessario confrontare i file di lingua con i riferimenti nel codice.

Terminal
# Step 1: Check which files are out of sync
npx i18n-validate sync --source locales/en.json --targets 'locales/*.json'

# Step 2: Auto-fill missing keys with source values (as placeholders)
npx i18n-validate sync \
  --source locales/en.json \
  --targets 'locales/*.json' \
  --fill-missing \
  --fill-value "[NEEDS TRANSLATION] {{source}}"

# Step 3: Remove stale keys no longer in source
npx i18n-validate sync \
  --source locales/en.json \
  --targets 'locales/*.json' \
  --remove-stale

# Step 4: Sort keys to match source order (cleaner diffs)
npx i18n-validate sync \
  --source locales/en.json \
  --targets 'locales/*.json' \
  --sort-keys

# All at once:
npx i18n-validate sync \
  --source locales/en.json \
  --targets 'locales/*.json' \
  --fill-missing \
  --remove-stale \
  --sort-keys
4

Automatizzare la sincronizzazione

La strategia di sincronizzazione più efficace combina tre livelli: 1) Hook pre-commit che convalidano la sincronizzazione a ogni commit. 2) Controlli nella pipeline CI che bloccano i merge con problemi. 3) Verifiche complete periodiche che rilevano i disallineamenti accumulati da correzioni urgenti e modifiche manuali.

.husky/pre-commit
# .husky/pre-commit
#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

# Check if source locale file changed
SOURCE_CHANGED=$(git diff --cached --name-only | grep -c 'locales/en.json')

if [ "$SOURCE_CHANGED" -gt 0 ]; then
  echo "Source locale changed - checking sync..."

  npx i18n-validate sync \
    --source locales/en.json \
    --targets 'locales/*.json' \
    --fail-on-missing \
    --min-coverage 90

  if [ $? -ne 0 ]; then
    echo ""
    echo "Translation files are out of sync!"
    echo "Run: npx i18n-validate sync --fill-missing"
    exit 1
  fi
fi
.github/workflows/i18n-sync.yml
# .github/workflows/i18n-sync.yml
name: Translation Sync Check

on:
  pull_request:
    paths:
      - 'locales/**'

jobs:
  sync-check:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

      - name: Check translation sync
        run: npx i18n-validate sync \
          --source locales/en.json \
          --targets 'locales/*.json' \
          --fail-on-missing \
          --min-coverage 95

      - name: Comment on PR if out of sync
        if: failure()
        uses: actions/github-script@v7
        with:
          script: |
            github.rest.issues.createComment({
              issue_number: context.issue.number,
              owner: context.repo.owner,
              repo: context.repo.repo,
              body: 'Translation files are out of sync. Please run npx i18n-validate sync --fill-missing and commit.'
            })
5

Rapporto sulla copertura delle traduzioni

La copertura delle traduzioni è la percentuale di chiavi di origine tradotte in ogni lingua di destinazione. i18n-validate genera un rapporto con le percentuali per lingua, evidenziando quelle in ritardo. Usi soglie di copertura nella CI per bloccare i merge quando la copertura scende sotto un livello accettabile.

Namespace-based sync
// Split large translation files by feature/namespace
// locales/
// ├── en/
// │   ├── common.json      (nav, footer, errors)
// │   ├── auth.json         (login, register, reset)
// │   ├── dashboard.json    (dashboard-specific)
// │   └── settings.json     (settings page)
// ├── de/
// │   ├── common.json
// │   ├── auth.json
// │   ├── dashboard.json
// │   └── settings.json

// Sync with namespace support:
npx i18n-validate sync \
  --source 'locales/en/*.json' \
  --targets 'locales/*/%.json' \
  --namespace-pattern '{locale}/{namespace}.json'

// Benefits:
// - Smaller files, easier to review
// - Feature teams own their translations
// - Lazy-load only needed namespaces
// - Parallel translation workflows
Imposti soglie di copertura diverse per lingue diverse. Le lingue principali (de, fr, ja) potrebbero richiedere il 100%, mentre quelle appena aggiunte (th, vi) potrebbero iniziare dall'80% e aumentare nel tempo.

Provi subito i18n Agent

Trascinare qui il file di traduzione

JSON, YAML, PO, XML, CSV, Markdown, Properties

oppure fare clic per selezionarlo

Lingue di destinazione

Nessuna registrazione richiestaPreventivo immediato

Domande frequenti sulla sincronizzazione dei file di traduzione