
Localização contínua sem TMS
O seu código é implementado continuamente. As traduções também devem ser. Saiba como automatizar a localização no seu fluxo de desenvolvimento.
O que é a localização contínua?
A localização contínua consiste em traduzir automaticamente novas cadeias como parte do fluxo de desenvolvimento, em vez de as agrupar em versões periódicas. Quando um programador acrescenta uma funcionalidade com cadeias de interface, estas são traduzidas antes do lançamento.
A abordagem tradicional
A maioria das equipas agrupa as traduções: recolhe novas cadeias, exporta-as para um TMS, aguarda pelos tradutores, importa os resultados e lança. Isto cria um estrangulamento que atrasa os lançamentos internacionais por dias ou semanas.
O programador acrescenta novas cadeias ao ficheiro regional de origem
As cadeias são exportadas e carregadas numa plataforma TMS
Os tradutores são notificados e começam a trabalhar
As traduções são revistas e aprovadas
Os ficheiros traduzidos são transferidos e reintegrados
A funcionalidade é lançada com traduções —dias ou semanas depois—
A abordagem nativa do IDE
Com tradução nativa do IDE, o programador traduz as cadeias como parte do fluxo habitual de programação. Sem exportar, carregar ou esperar: as traduções surgem na mesma sessão de desenvolvimento.
O programador acrescenta novas cadeias ao ficheiro regional de origem
O programador pede ao assistente de IA para traduzir o ficheiro
Os ficheiros traduzidos são gravados diretamente no projeto
A funcionalidade é lançada com as traduções no mesmo commit
A abordagem tradicional
6 steps
Multiple tools and platforms
Days to weeks per cycle
A abordagem nativa do IDE
4 steps
Inside your editor
Same commit
Configurar o pipeline de tradução
As equipas que pretendam automatizar além do IDE podem adicionar uma etapa de CI/CD que traduza cadeias novas ou alteradas em cada envio para main. Funciona com GitHub Actions, GitLab CI ou qualquer sistema de CI/CD.
Comece com tradução nativa do IDE em equipas pequenas. Acrescente automatização de CI/CD quando a equipa ultrapassar 3 a 4 programadores ou precisar de garantir traduções em cada integração com 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 pushAdicionar o controlo de qualidade da tradução a CI
As verificações automáticas no pipeline de CI detetam traduções em falta, marcadores danificados e formatos de mensagens ICU inválidos antes de chegarem à produção. São scripts simples que comparam o ficheiro regional de origem com todas as regiões de destino.
#!/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
doneValidar traduções em CI
Detetar e tratar a divergência das traduções
A divergência ocorre quando as cadeias de origem mudam, mas as traduções não são atualizadas. O inglês diz «Save changes», mas o alemão continua a mostrar o texto antigo. A deteção compara os carimbos de data/hora ou os hashes do conteúdo dos ficheiros de origem e tradução.
#!/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"Escolher a abordagem de tradução
Nem todo o conteúdo precisa da mesma abordagem. As cadeias e etiquetas da interface funcionam muito bem com IA. Os textos de marketing beneficiam de IA e revisão humana. Os textos jurídicos e de conformidade devem utilizar sempre tradutores humanos profissionais.
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 | PremiumFluxo Git para traduções
Traduza no ramo da funcionalidade antes de integrar, não depois. Assim, todas as integrações em main incluem traduções completas. Adicione uma verificação prévia que confirme a integridade das traduções em todas as regiões compatíveis.
Os ficheiros JSON regionais grandes provocam conflitos frequentes quando vários ramos os alteram em simultâneo. Ordene as chaves alfabeticamente e utilize uma chave por linha para reduzir as diferenças e facilitar a resolução dos conflitos.
# .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');
\""Erros frequentes
Tratar a localização como uma etapa posterior ao desenvolvimento
Sem validação das traduções ao nível de CI
Excesso de complexidade com um TMS
Não acompanhar a atualidade das traduções
Experimente já o i18n Agent
Largue aqui o seu ficheiro de tradução
JSON, YAML, PO, XML, CSV, Markdown, Properties
ou clique para selecionar
Idiomas de destino