Skip to main content

TMS を使わない継続的ローカリゼーション

コードを継続的にデプロイするなら、翻訳も継続的に更新すべきです。開発ワークフローでローカリゼーションを自動化する方法を解説します。

継続的ローカリゼーションとは?

継続的ローカリゼーションとは、翻訳を定期リリースごとにまとめて処理するのではなく、開発ワークフローの一環として新しい文字列を自動的に翻訳する手法です。開発者が UI 文字列を含む新機能を追加すると、その機能をリリースする前に文字列が翻訳されます。

従来の方法

多くのチームでは、翻訳をまとめて処理しています。新しい文字列を収集して TMS にエクスポートし、翻訳を待ってから結果をインポートし、リリースします。この方法ではローカリゼーションがボトルネックとなり、国際版のリリースが数日から数週間遅れます。

1

開発者が翻訳元のロケールファイルに新しい文字列を追加

2

文字列をエクスポートし、TMS プラットフォームへアップロード

3

翻訳者に通知が届き、翻訳作業が始まる

4

翻訳をレビューして承認

5

翻訳済みファイルをダウンロードし、コードへ再びマージ

6

翻訳を含む機能をリリース(数日から数週間後)

Days to weeks

IDE ネイティブの方法

IDE ネイティブ翻訳では、開発者が通常のコーディング作業の一環として文字列を翻訳します。エクスポート、アップロード、待ち時間は不要で、開発と同じセッション内で翻訳が完了します。

1

開発者が翻訳元のロケールファイルに新しい文字列を追加

2

開発者が AI アシスタントにファイルの翻訳を依頼

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 の範囲を超えて翻訳を自動化するチームでは、main への push ごとに新規または変更された文字列を翻訳する CI/CD ステップを追加します。GitHub Actions、GitLab CI、その他のあらゆる CI/CD システムで利用できます。

小規模チームでは、まず IDE ネイティブ翻訳を使用してください。開発者が 3~4 名を超えたとき、または main へのマージごとに翻訳を確実に用意する必要が生じたときに、CI/CD 自動化を追加します。

既存の 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

翻訳 QA を CI に追加

CI パイプラインの自動チェックにより、不足している翻訳、壊れたプレースホルダー、不正な ICU メッセージ形式を本番環境に到達する前に検出できます。翻訳元のロケールファイルとすべての対象ロケールを比較する簡単なスクリプトで実現できます。

CI レベルの翻訳検証がないと、不足している翻訳が本番環境へそのまま到達します。ユーザーには翻訳済みテキストではなく、"settings.title" のような未処理のキーや空の文字列が表示されます。CI で 5 分間チェックするだけで、完全に防止できます。
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 で翻訳を検証

CI パイプラインに i18n-validate を追加し、キー不足、壊れたプレースホルダー、複数形の問題を自動的に検出します。i18n-pseudo で疑似翻訳を生成し、ビジュアルリグレッションテストに使用できます。
5

翻訳ドリフトを検出して処理

翻訳ドリフトとは、翻訳元の文字列が変更されても翻訳が更新されない状態です。英語が "Save changes" に変わったのに、ドイツ語では以前の文言が残っているようなケースです。ドリフトの検出では、翻訳元と翻訳ファイルのタイムスタンプまたはコンテンツハッシュを比較します。

古い翻訳は、翻訳がない状態よりも深刻です。翻訳がなければ、キーまたはフォールバック言語が表示されるため、誤りだと明らかに分かります。古い翻訳は誤った内容を自然に伝えるため、ユーザーを誤解させたり、サポート上の問題を引き起こしたりする可能性があります。
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

翻訳方法を選択

すべてのコンテンツに同じ翻訳方法が適するわけではありません。UI 文字列やラベルには AI 翻訳が効果的です。マーケティングコピーには、AI と人によるレビューの組み合わせが適しています。法務文書とコンプライアンス関連のテキストでは、必ずプロの翻訳者を使用してください。

一般的なアプリ文字列の 80% 以上は、AI 翻訳によって本番環境で利用できる品質に仕上げられます。ニュアンスが特に重要となる法務文書、ブランドボイス、文化的に配慮が必要なコンテンツには、人の翻訳者を起用してください。
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 ロケールファイルでは、複数のブランチが同時に変更するとマージ競合が頻繁に発生します。キーをアルファベット順に並べ、1 行に 1 キーを記述して差分を小さくし、競合を解決しやすくしてください。

翻訳ファイルはコードとともにリポジトリへ保存します。バージョン管理され、プルリクエストでレビューでき、その他のファイルと同じパイプラインでデプロイされます。
.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 は、人の翻訳者によるワークフローを管理するために設計されています。AI 翻訳を使用する場合、TMS の管理負担は不要かもしれません。まずは IDE または CI/CD で翻訳する簡単な方法から始め、人の翻訳者を管理する必要が生じた場合にだけ TMS を追加してください。

翻訳の鮮度を追跡しない

鮮度を追跡しなければ、どの翻訳が古いか分かりません。翻訳元の文字列が変更されても、以前の翻訳が残り続けます。古いコンテンツを検出するため、ワークフローにドリフト検出を組み込んでください。

i18n Agent を今すぐ試す

翻訳ファイルをここにドロップ

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

またはクリックしてファイルを選択

翻訳先言語

登録不要すぐに見積もり

よくある質問