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에 푸시할 때마다 새 문자열이나 변경된 문자열을 번역하는 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

CI에 번역 QA 추가

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 로케일 파일을 동시에 수정하면 병합 충돌이 자주 발생해요. 키를 알파벳순으로 정렬하고 한 줄에 키 하나만 사용해 변경 내역을 최소화하고 충돌을 쉽게 해결하세요.

번역 파일은 코드와 함께 저장소에 있어요. 버전 관리할 수 있고 풀 리퀘스트에서 검토할 수 있으며 다른 모든 파일과 같은 파이프라인으로 배포할 수 있어요.
.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

또는 클릭하여 파일 선택

대상 언어

가입 불필요즉시 견적

자주 묻는 질문