Skip to main content

Непрерывная локализация без TMS

Ваш код развёртывается непрерывно. Переводы должны делать то же самое. Узнайте, как автоматизировать локализацию в процессе разработки.

Что такое непрерывная локализация?

Непрерывная локализация — автоматический перевод новых строк в рамках процесса разработки вместо объединения переводов в периодические выпуски. Когда разработчик добавляет новую функцию со строками интерфейса, они переводятся до выпуска функции.

Традиционный подход

Большинство команд объединяют переводы в пакеты: собирают новые строки, экспортируют их в TMS, ждут переводчиков, импортируют результаты и лишь затем выпускают продукт. Это создаёт узкое место локализации, которое задерживает международные выпуски на несколько дней или недель.

1

Разработчик добавляет новые строки в файл исходной локали

2

Строки экспортируются и загружаются на платформу TMS

3

Переводчики получают уведомление и начинают работу

4

Переводы проверяются и утверждаются

5

Переведённые файлы скачиваются и объединяются с кодовой базой

6

Функция выпускается с переводами через несколько дней или недель

Days to weeks

Подход на основе IDE

При переводе непосредственно в IDE разработчик обрабатывает строки в рамках обычного процесса написания кода. Без экспорта, загрузки и ожидания: перевод выполняется в том же сеансе, что и разработка.

1

Разработчик добавляет новые строки в файл исходной локали

2

Разработчик просит своего ИИ-помощника перевести файл

3

Переведённые файлы записываются непосредственно в проект

4

Функция выпускается с переводами в той же фиксации

Same commit

Традиционный подход

6 steps

Multiple tools and platforms

Days to weeks per cycle

Подход на основе IDE

4 steps

Inside your editor

Same commit

3

Настроить конвейер перевода

Команды, которым нужен автоматический перевод за пределами IDE, могут добавить этап CI/CD для перевода новых или изменённых строк при каждой отправке в main. Это работает с GitHub Actions, GitLab CI и любой другой системой CI/CD.

Небольшим командам стоит начать с перевода в IDE. Добавьте автоматизацию CI/CD, когда в команде станет больше 3-4 разработчиков или если переводы должны гарантированно выполняться при каждом слиянии в main.

Добавьте перевод как этап существующего конвейера CI/CD. Он выполняется после успешной сборки и до развёртывания, чтобы каждый выпуск содержал актуальные переводы.
.github/workflows/translate.yml
# .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
# .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 push
4

Добавить контроль качества перевода в CI

Автоматические проверки в конвейере CI выявляют отсутствующие переводы, нарушенные заполнители и недопустимые форматы сообщений ICU до их попадания в рабочую среду. Это простые сценарии, которые сравнивают файл исходной локали со всеми целевыми локалями.

Без проверки переводов на уровне CI отсутствующие строки незаметно попадают в рабочую среду. Вместо переведённого текста пользователи видят исходные ключи вроде "settings.title" или пустые строки. Пятиминутная проверка CI полностью предотвращает эту проблему.
check-translations.sh
#!/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
check-placeholders.sh
#!/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
done

Проверять переводы в CI

Добавьте i18n-validate в конвейер CI, чтобы автоматически выявлять отсутствующие ключи, нарушенные заполнители и проблемы с множественным числом. Используйте i18n-pseudo для создания искусственных переводов при визуальном регрессионном тестировании.
5

Обнаруживать и устранять расхождение переводов

Расхождение возникает, когда исходные строки меняются, а переводы не обновляются. В английской версии уже написано «Сохранить изменения», а в немецкой остаётся старый текст. Для выявления расхождения сравниваются временные метки или хеши содержимого исходного файла и файлов перевода.

Устаревшие переводы хуже отсутствующих. Отсутствие перевода очевидно: пользователь видит ключ или резервный язык. Устаревший перевод убедительно сообщает неверную информацию, что может ввести пользователей в заблуждение или вызвать обращения в поддержку.
detect-drift.sh
#!/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"
6

Выбрать подход к переводу

Не для каждого содержимого подходит один и тот же способ перевода. Строки и названия элементов интерфейса отлично переводятся с помощью ИИ. Маркетинговые тексты выигрывают от ИИ с проверкой человеком. Юридические материалы и тексты о соблюдении требований всегда следует поручать профессиональным переводчикам.

ИИ переводит более 80% обычных строк приложения с качеством, достаточным для рабочей среды. Оставьте переводчикам юридические тексты, материалы с фирменным стилем и культурно чувствительное содержимое, где особенно важны нюансы.
Cost Comparison
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 | Premium
7

Процесс Git для переводов

Переводите в ветке функции до слияния, а не после. Тогда каждое слияние в main будет содержать полные переводы. Добавьте проверку перед слиянием, которая подтверждает полноту переводов для всех поддерживаемых локалей.

Крупные файлы локалей JSON часто вызывают конфликты слияния, когда несколько веток изменяют их одновременно. Сортируйте ключи по алфавиту и размещайте по одному ключу в строке, чтобы уменьшить различия и упростить разрешение конфликтов.

Файлы перевода находятся в Вашем репозитории рядом с кодом. Они управляются версиями, проверяются в запросах на слияние и развёртываются тем же конвейером, что и всё остальное.
.gitattributes + package.json
# .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');
\""

Распространённые ошибки

Локализация после завершения разработки

Главная ошибка — ждать завершения разработки перед переводом. Это создаёт узкие места, задерживает выпуски и превращает переводы во второстепенную задачу. Переводите во время разработки, а не после.

Нет проверки перевода на уровне CI

Без автоматических проверок отсутствующие переводы, нарушенные заполнители и недопустимые форматы попадают в рабочую среду. Добавьте в конвейер CI проверку полноты и формата.

Избыточно сложное решение с TMS

TMS создавались для управления работой переводчиков. При переводе с помощью ИИ издержки TMS могут быть не нужны. Начните с простого: переводите в IDE или CI/CD и добавляйте TMS, только если потребуется управлять переводчиками.

Актуальность переводов не отслеживается

Без отслеживания актуальности Вы не знаете, какие переводы устарели. Исходные строки меняются, а старые переводы остаются. Встройте выявление расхождений в свой процесс, чтобы находить устаревшее содержимое.

Попробовать i18n Agent

Перетащите сюда файл перевода

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

или нажмите, чтобы выбрать

Целевые языки

Регистрация не требуетсяМгновенный расчёт

Часто задаваемые вопросы