
Localizare continuă fără un TMS
Codul dumneavoastră este implementat continuu. La fel ar trebui să fie și traducerile. Aflați cum să automatizați localizarea în fluxul de dezvoltare.
Ce este localizarea continuă?
Localizarea continuă este practica de a traduce automat șirurile noi ca parte a fluxului de dezvoltare, în loc de a grupa traducerile în versiuni periodice. Când un dezvoltator adaugă o funcționalitate nouă cu șiruri de interfață, acestea sunt traduse înainte de lansarea funcționalității.
Abordarea tradițională
Majoritatea echipelor grupează traducerile: colectează șirurile noi, le exportă într-un TMS, așteaptă traducătorii, importă rezultatele și apoi lansează versiunea. Astfel apare un blocaj în procesul de localizare, care întârzie lansările internaționale cu zile sau săptămâni.
Dezvoltatorul adaugă șiruri noi în fișierul limbii-sursă
Șirurile sunt exportate și încărcate pe o platformă TMS
Traducătorii sunt notificați și încep lucrul
Traducerile sunt verificate și aprobate
Fișierele traduse sunt descărcate și integrate înapoi
Funcționalitatea este lansată cu traduceri (după câteva zile sau săptămâni)
Abordarea integrată în IDE
Cu traducerea integrată în IDE, dezvoltatorul traduce șirurile ca parte a fluxului obișnuit de programare. Fără export, fără încărcare, fără așteptare — traducerile sunt realizate în aceeași sesiune de dezvoltare.
Dezvoltatorul adaugă șiruri noi în fișierul limbii-sursă
Dezvoltatorul îi solicită asistentului bazat pe IA să traducă fișierul
Fișierele traduse sunt scrise direct în proiect
Funcționalitatea este lansată cu traducerile incluse în același commit
Abordarea tradițională
6 steps
Multiple tools and platforms
Days to weeks per cycle
Abordarea integrată în IDE
4 steps
Inside your editor
Same commit
Configurați fluxul de traducere
Pentru echipele care doresc traducere automată și în afara IDE-ului, adăugați un pas CI/CD care traduce șirurile noi sau modificate la fiecare push în ramura main. Această soluție funcționează cu GitHub Actions, GitLab CI sau orice sistem CI/CD.
Începeți cu traducerea integrată în IDE dacă aveți o echipă mică. Adăugați automatizarea CI/CD când echipa depășește 3-4 dezvoltatori sau când aveți nevoie ca traducerile să fie garantate la fiecare integrare în ramura main.
# .github/workflows/translate.yml
name: Translate
on:
push:
branches: [main]
paths: ['locales/en/**']
jobs:
translate:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Translate changed strings
run: |
npx i18n-agent translate locales/en.json \
--to de,ja,es,fr,ko,zh-Hans \
--api-key ${{ secrets.I18N_AGENT_API_KEY }}
- name: Commit translations
run: |
git config user.name "github-actions"
git config user.email "[email protected]"
git add locales/
git diff --cached --quiet || git commit -m "chore: update translations"
git push# .gitlab-ci.yml
translate:
stage: deploy
only:
changes:
- locales/en/**
script:
- npx i18n-agent translate locales/en.json
--to de,ja,es,fr --api-key $I18N_AGENT_API_KEY
- git add locales/ && git commit -m "chore: translations" && git pushAdăugați controlul calității traducerilor în CI
Verificările automate din fluxul CI detectează traducerile lipsă, substituenții nevalizi și formatele de mesaje ICU nevalide înainte ca acestea să ajungă în producție. Acestea sunt scripturi simple care compară fișierul limbii-sursă cu toate limbile-țintă.
#!/bin/bash
# check-translations.sh — Run in CI to catch missing translations
SOURCE="locales/en.json"
LANGS=("de" "ja" "es" "fr")
EXIT_CODE=0
# Extract all keys from source
SOURCE_KEYS=$(jq -r '[paths(scalars)] | map(join(".")) | .[]' "$SOURCE" | sort)
SOURCE_COUNT=$(echo "$SOURCE_KEYS" | wc -l)
for lang in "${LANGS[@]}"; do
TARGET="locales/$lang.json"
if [ ! -f "$TARGET" ]; then
echo "❌ Missing: $TARGET"
EXIT_CODE=1
continue
fi
TARGET_KEYS=$(jq -r '[paths(scalars)] | map(join(".")) | .[]' "$TARGET" | sort)
MISSING=$(comm -23 <(echo "$SOURCE_KEYS") <(echo "$TARGET_KEYS"))
if [ -n "$MISSING" ]; then
COUNT=$(echo "$MISSING" | wc -l)
echo "❌ $lang: $COUNT missing keys"
echo "$MISSING" | head -5
EXIT_CODE=1
else
echo "✅ $lang: all $SOURCE_COUNT keys present"
fi
done
exit $EXIT_CODE#!/bin/bash
# check-placeholders.sh — Validate placeholder consistency
SOURCE="locales/en.json"
LANGS=("de" "ja" "es")
for lang in "${LANGS[@]}"; do
TARGET="locales/$lang.json"
# Compare placeholders like {{name}}, {count}, %s, %d
jq -r 'paths(scalars) as $p | [($p | join(".")), (getpath($p))]
| @tsv' "$SOURCE" | while IFS=$'\t' read -r key value; do
SOURCE_PH=$(echo "$value" | grep -oE '\{\{[^}]+\}\}|%[sd@]' | sort)
TARGET_VAL=$(jq -r "getpath($(echo $key | jq -R 'split(".")'))" "$TARGET")
TARGET_PH=$(echo "$TARGET_VAL" | grep -oE '\{\{[^}]+\}\}|%[sd@]' | sort)
if [ "$SOURCE_PH" != "$TARGET_PH" ]; then
echo "❌ $lang/$key: placeholder mismatch"
echo " Source: $SOURCE_PH"
echo " Target: $TARGET_PH"
fi
done
doneValidați traducerile în CI
Detectați și gestionați decalajul traducerilor
Decalajul traducerilor apare atunci când șirurile sursă se modifică, dar traducerile nu sunt actualizate. Textul în limba engleză spune „Salvați modificările”, însă cel în limba germană afișează încă textul vechi. Detectarea decalajului compară marcajele temporale sau hashurile conținutului fișierelor-sursă și traduse.
#!/bin/bash
# detect-drift.sh — Find stale translations
SOURCE="locales/en.json"
SOURCE_HASH=$(md5sum "$SOURCE" | cut -d' ' -f1)
HASH_FILE=".translation-hashes"
# Compare current source hash with stored hash
if [ -f "$HASH_FILE" ]; then
STORED_HASH=$(grep "^en:" "$HASH_FILE" | cut -d: -f2)
if [ "$SOURCE_HASH" != "$STORED_HASH" ]; then
echo "⚠️ Source strings changed since last translation"
echo " Run translations to update all locales"
# Show which keys changed
git diff HEAD~1 "$SOURCE" | grep '^[+-]' | grep -v '^[+-][+-]'
fi
fi
# Update stored hash
echo "en:$SOURCE_HASH" > "$HASH_FILE"Alegeți abordarea de traducere
Nu toate tipurile de conținut necesită aceeași abordare de traducere. Șirurile și etichetele interfeței se pretează foarte bine traducerii cu IA. Textele de marketing beneficiază de traducere cu IA și verificare umană. Textele juridice și de conformitate trebuie traduse întotdeauna de traducători profesioniști.
Translation Approach Comparison:
Content Type | Approach | Cost/word | Quality
─────────────────────┼───────────────────┼────────────┼──────────
UI strings, labels | AI/LLM | $0.001-01 | Production
Tooltips, help text | AI/LLM | $0.001-01 | Production
Marketing copy | AI + human review | $0.05-0.15 | High
Legal / compliance | Human translator | $0.15-0.40 | Certified
Brand voice content | Human translator | $0.20-0.50 | PremiumFluxul Git pentru traduceri
Traduceți în ramura funcționalității înainte de integrare, nu după. Astfel, fiecare integrare în ramura main va include traduceri complete. Adăugați o verificare înainte de integrare care confirmă integralitatea traducerilor pentru toate limbile acceptate.
Fișierele JSON mari pentru limbi provoacă frecvent conflicte de integrare atunci când mai multe ramuri le modifică simultan. Sortați cheile alfabetic și folosiți câte o cheie pe linie pentru a reduce dimensiunea diferențelor și a simplifica soluționarea conflictelor.
# .gitattributes — reduce merge conflicts in locale files
locales/*.json merge=union
# Sort keys alphabetically to minimize diffs:
# package.json script:
"sort-locales": "node -e \"
const fs = require('fs');
const f = process.argv[1];
const d = JSON.parse(fs.readFileSync(f));
const s = (o) => Object.keys(o).sort().reduce((r,k) =>
({...r, [k]: typeof o[k]==='object' ? s(o[k]) : o[k]}), {});
fs.writeFileSync(f, JSON.stringify(s(d), null, 2)+'\\n');
\""Capcane frecvente
Tratarea localizării ca etapă ulterioară dezvoltării
Lipsa validării traducerilor la nivel de CI
Complicarea excesivă cu un TMS
Neurmărirea actualității traducerilor
Încercați acum i18n Agent
Plasați aici fișierul de traducere
JSON, YAML, PO, XML, CSV, Markdown, Properties
sau faceți clic pentru a-l selecta
Limbi țintă