23. 국제화 가이드

0. 먼저 알고 가기 (30초 요약)

  • 번역 키는 기능 요구보다 먼저 만들어져야 유지보수가 쉬워집니다.
  • 숫자/날짜/문장 길이까지 언어별 차이를 먼저 반영하면 QA 비용이 줄어듭니다.
  • 릴리즈마다 누락 키를 회귀 검사하도록 자동화하세요.

왜 중요한가: 국제화는 "번역만 하면 끝"이 아닙니다. 문장 길이, 숫자/날짜 포맷, 방향성, SEO, 폰트, 캐시 키까지 영향을 받기 때문에, 나중에 추가하면 모든 화면을 재작업해야 하는 큰 부채가 됩니다.

일상 비유: 옷 사이즈 표기와 같습니다. S/M/L만 적은 옷은 한국에서는 통해도, 유럽에서는 cm와 inch를 함께 표기해야 환불률이 줄어듭니다. "한 번 잘 설계하면 모든 시장에서 통하는" 영역입니다.

초심자용 한눈에 보기

국제화는 번역 품질뿐 아니라 운영까지 잡아야 하는 실무 주제입니다.

flowchart LR
  L[Locale 결정] --> M[메시지 키 + ICU]
  M --> F[Fallback 규칙]
  F --> P[Pseudo-loc/RTL smoke]
  P --> S[SEO/hreflang]
  S --> O[운영 모니터링]

핵심 용어 빠르게 정리

용어 쉬운 뜻
locale 지역/언어 설정 값(ko-KR 등)
번역 키 다국어 문자열을 찾는 고유 식별자
placeholder 변수 치환 부분 예: {name}
RTL 오른쪽에서 왼쪽으로 쓰는 언어 정렬 방향
용어집 품질을 맞추기 위해 통일한 번역 사전
분류 제품 품질 & 글로벌 상태 Stable
연관 가이드 02. React 19, 08. 성능, 19. 접근성, 24. SEO 도구 원칙 벤더 중립
핵심 테마 locale routing, ICU message, 번역 QA, pseudo-localization, RTL, fallback, SEO Update 최신 기준

국제화 표준은 특정 번역 SaaS나 AI 모델 사용법이 아니라 언어, 지역, 방향성, 포맷, 검색 노출, 번역 품질을 제품 구조 안에서 지속 가능하게 관리하는 방식입니다.


추천 항목 (실무 우선순위)

  • 시작 추천: locale 우선순위(URL/쿠키/헤더)와 fallback 규칙을 먼저 정합니다.
  • 안정 추천: 번역 키 충돌/누락을 CI에서 잡고, 중요 문구는 번역 품질 샘플로 사전 검증하세요.
  • 운영 추천: RTL, 통화/날짜 포맷은 지역별 테스터 계정으로 주기 점검합니다.

추천 항목 고도화 체크

  • 첫 적용 — locale routing, ICU message, fallback, RTL smoke 중 하나를 실제 PR이나 운영 이슈에 붙이고, 변경 전 기준을 먼저 적는다.
  • 증거 정리 — message compile, placeholder diff, pseudo-loc screenshot, hreflang 검사를 같은 작업 기록에 남긴다.
  • 재점검 — missing key, overflow defect, locale SEO mismatch가 나아졌는지 30일 안에 확인하고 기준을 유지, 수정, 폐기 중 하나로 판정한다.

추천 항목 실행 기록 템플릿

  • 작업 : locale routing, ICU message, fallback, RTL smoke 적용 범위를 어느 화면, 패키지, 문서에 둘지 적는다.
  • 증거 : message compile, placeholder diff, pseudo-loc screenshot, hreflang 검사 중 실제로 남긴 항목만 링크한다.
  • 판정 : 유지/수정/폐기 중 하나와 이유를 한 문장으로 남긴다.
  • 다음 점검 : missing key, overflow defect, locale SEO mismatch를 다시 볼 날짜와 담당자를 지정한다.

문서 책임 범위

이 문서가 결정하는 것 단일 출처로 따르는 문서
locale 결정, message format, fallback, pseudo-localization 02. React 19, 07. 테스팅
hreflang, canonical, localized metadata 24. SEO 메타데이터
RTL, accessible name, 번역 후 UI 접근성 19. 웹 접근성, 20. 디자인 시스템
AI 번역 사용과 민감정보/검증 책임 18. AI 개발 워크플로우

0. 모든 프론트엔드 그룹 공통 Baseline

영역 공통 기준 검증 방법
Locale 전략 URL, 쿠키, 계정 설정, 브라우저 언어 우선순위 명시 routing test
Message format 변수, plural, select, date/number 포맷을 구조화 compile check
Fallback 누락 번역, 미지원 locale, 오래된 번역 fallback 정의 missing key report
Pseudo-localization UI overflow와 hard-coded text 검출 visual smoke
RTL layout, icon direction, focus order, motion direction 검증 RTL test
SEO canonical, hreflang, localized metadata 관리 SEO audit
QA placeholder 보존, 용어집, tone, 길이, 접근성 검수 translation QA

0.0 국제화 처리 플로우

flowchart TD
  A[요청/라우트 진입] --> B[Locale 판별]
  B --> C[메시지 키 로드 및 ICU 컴파일]
  C --> D{누락 키 또는 변수 불일치}
  D -->|있음| E[빌드 실패 + 번역 보강]
  D -->|없음| F[출력 렌더 및 날짜/숫자 포맷 적용]
  F --> G[Pseudo-localization + RTL smoke]
  G --> H{문장 길이/문맥 이슈}
  H -->|있음| I[UI 반영/번역 수정]
  H -->|없음| J[SEO/Hreflang/canonical 반영]
  E --> C
  I --> F
  J --> K[릴리즈 증적 및 locale KPI 모니터링]

0.1 교차 검증 매트릭스

권고 1차 출처 실행 증거 운영 증거 철회 조건
메시지는 ICU/plural/select 같은 구조화 format을 사용한다 Unicode CLDR/ICU MessageFormat compile check, placeholder diff 번역 오류, locale-specific bug 단일 언어 또는 극소수 정적 copy만 다룰 때
URL locale, canonical, hreflang을 일관되게 관리한다 검색엔진/HTML link relation 문서 route SEO test, sitemap validation indexed locale mismatch 검색 노출이 필요 없는 내부 도구일 때
pseudo-localization을 release smoke에 포함한다 i18n QA best practice visual overflow test, hard-coded text scan overflow defect, missing key count 번역 대상 UI가 아직 없을 때
RTL은 logical property와 컴포넌트 테스트로 검증한다 CSS logical properties, WAI/WCAG RTL visual diff, keyboard navigation RTL-only defect, support ticket 지원 locale에 RTL 언어가 없을 때

0.2 운영 게이트

Gate Evidence Owner Rollback
Locale 추가 routing test, fallback rule, SEO metadata 확인 I18n owner locale 비활성화 또는 제한 공개
메시지 변경 ICU compile, placeholder diff, missing key report Content owner 이전 번역 복구 또는 fallback 적용
Pseudo/RTL smoke overflow screenshot, hard-coded text scan, RTL keyboard test QA owner release 차단 또는 affected locale 제외
SEO 국제화 canonical/hreflang/sitemap validation SEO owner sitemap 제외 또는 canonical rollback

0.2.1 Locale 공개 전 증거 흐름

flowchart LR
  COPY["source copy 변경"] --> MSG["ICU message + placeholder"]
  MSG --> COMPILE{"compile/pass?"}
  COMPILE -->|"fail"| FIX_COPY["키/placeholder 수정"]
  FIX_COPY --> MSG
  COMPILE -->|"pass"| VISUAL["pseudo-loc screenshot"]
  VISUAL --> RTL{"RTL 또는 긴 문장<br/>영향 있음?"}
  RTL -->|"있음"| LAYOUT["logical property/focus/motion 점검"]
  RTL -->|"없음"| SEO
  LAYOUT --> SEO["localized metadata + hreflang"]
  SEO --> FLAG{"locale flag<br/>부분 공개 가능?"}
  FLAG -->|"예"| CANARY["locale canary + KPI 모니터링"]
  FLAG -->|"아니오"| HOLD["공개 보류"]
  CANARY --> RELEASE["정식 공개"]

1. Locale 결정 규칙

왜 중요한가: locale 우선순위가 서버/클라이언트/SEO마다 다르면 한 사용자가 한 페이지에서 서로 다른 언어가 섞여 보입니다. hydration 불일치 버그의 가장 흔한 원인입니다.

우선순위 기준
1 사용자가 명시적으로 선택한 locale
2 로그인 사용자의 저장된 preference
3 URL path/domain의 locale
4 브라우저 Accept-Language
5 제품 기본 locale

locale 결정 규칙은 서버 렌더링, 클라이언트 라우팅, API 호출, SEO metadata에서 동일하게 적용되어야 합니다.

1.1 Locale 결정 의사결정 트리

flowchart TD
  START([요청 진입]) --> EXPLICIT{URL에<br/>locale switch?}
  EXPLICIT -->|예| USE_EXPLICIT[명시 선택 locale]
  EXPLICIT -->|아니오| LOGIN{로그인 사용자?}
  LOGIN -->|예| HAS_PREF{저장된<br/>preference 존재?}
  HAS_PREF -->|예| USE_PREF[저장된 preference]
  HAS_PREF -->|아니오| URL_CHECK
  LOGIN -->|아니오| URL_CHECK
  URL_CHECK{URL path<br/>또는 domain에<br/>locale 표시?}
  URL_CHECK -->|예| USE_URL[URL locale]
  URL_CHECK -->|아니오| ACCEPT{Accept-Language<br/>헤더에 지원 locale?}
  ACCEPT -->|예| USE_ACCEPT[브라우저 우선 locale]
  ACCEPT -->|아니오| USE_DEFAULT[제품 기본 locale]
  USE_EXPLICIT --> RENDER[렌더링]
  USE_PREF --> RENDER
  USE_URL --> RENDER
  USE_ACCEPT --> RENDER
  USE_DEFAULT --> RENDER

1.2 신규 언어/로케일 추가 시퀀스

sequenceDiagram
  participant PM as PM
  participant DEV as Frontend Dev
  participant TR as Translator
  participant CI as CI Pipeline
  participant SEO as SEO Owner
  participant OPS as Ops

  PM->>DEV: 신규 locale ko-KR 추가 요청
  DEV->>DEV: locales/ko-KR 디렉토리 생성
  DEV->>DEV: 메시지 키 골격 복제 (en 기준)
  DEV->>TR: 번역 요청 + screenshot/context
  TR->>DEV: 번역 파일 PR
  DEV->>CI: PR 푸시
  CI->>CI: ICU compile + placeholder diff
  CI->>CI: missing key 검사
  CI->>CI: pseudo-loc + RTL smoke
  CI-->>DEV: 모든 게이트 통과
  DEV->>SEO: hreflang/canonical/sitemap 추가
  SEO->>SEO: localized metadata 작성
  DEV->>OPS: locale 활성화 플래그 ON
  OPS->>OPS: locale별 KPI 대시보드 확인
  OPS-->>PM: 신규 locale 정식 공개

비유: 새 매장을 오픈하는 것과 같습니다. 메뉴판(번역) → 가격표(숫자/통화) → 간판(SEO) → POS 시스템(라우팅) 순서로 준비해야 첫 손님이 헤매지 않습니다.


2. 메시지 작성 원칙

왜 중요한가: 문장 조각을 이어 붙이는 방식은 영어에서는 자연스러워도, 어순/조사/관사가 다른 언어에서는 문법이 깨집니다. ICU 같은 구조화 포맷을 처음부터 쓰는 것이 가장 저렴한 보험입니다.

원칙 기준
문장 단위 단어 조각을 이어 붙이지 않음
변수 명확화 {count}, {userName}처럼 의미 있는 이름
plural/select 사용 수량과 성별/상태 분기를 문법적으로 처리
HTML 분리 번역 문자열에 임의 HTML 삽입 금지
문맥 제공 번역자에게 화면, 목적, 제한 길이 제공
{
  "cart.items": "{count, plural, =0 {No items} one {# item} other {# items}}",
  "order.status": "{status, select, paid {Paid} failed {Failed} pending {Pending} other {Unknown}}"
}

2.1 ICU 메시지 처리 흐름

flowchart TD
  SRC[메시지 키 source] --> COMPILE[ICU 컴파일러]
  COMPILE -->|문법 오류| FAIL_COMPILE[빌드 실패<br/>리뷰 차단]
  COMPILE -->|성공| AST[AST 산출]
  AST --> EXTRACT[placeholder 목록 추출]
  EXTRACT --> DIFF{소스 vs 번역<br/>placeholder 일치?}
  DIFF -->|불일치| FAIL_DIFF[CI 실패<br/>번역 수정 요청]
  DIFF -->|일치| RUNTIME[런타임 메시지 빌더]
  RUNTIME --> VARS{입력 변수 모두 제공?}
  VARS -->|아니오| FALLBACK[fallback 적용<br/>+ 모니터링 경고]
  VARS -->|예| RENDER[최종 렌더 문자열]
  RENDER --> INTL[Intl.NumberFormat<br/>Intl.DateTimeFormat 적용]
  INTL --> OUT[화면 출력]

비유: 케이크 데코레이션 틀과 같습니다. 글자 한 줄을 직접 짜내는 게 아니라, "이 자리에 이름, 이 자리에 나이"라는 틀(ICU)에 맞춰 짜야 모든 케이크가 일관됩니다.


3. 번역 키 구조

방식 기준
Domain 기반 checkout.payment.submit
Component 기반 재사용 컴포넌트 내부 label
Error 기반 error.network.timeout
Metadata 기반 seo.product.title

키 이름은 화면 위치보다 의미를 담아야 합니다. button.submit보다 checkout.payment.submit이 추적과 변경에 유리합니다.


4. 번역 QA

검사 기준
누락 키 build 또는 CI에서 실패
미사용 키 주기적으로 정리
placeholder 원문과 번역의 변수 목록 일치
ICU syntax compile 단계에서 검증
길이 버튼, 탭, 카드, 표에서 overflow 확인
용어집 제품 용어와 금지어 검사
접근성 번역 후 accessible name 의미 유지

AI 번역을 사용하더라도 placeholder, plural, tone, legal copy는 자동 검증과 사람 검토가 필요합니다.


5. Pseudo-localization

Pseudo-localization은 실제 번역 전에 UI 구조 문제를 찾는 가장 저렴한 방법입니다.

검출 대상 예시
hard-coded text 번역 파일을 거치지 않는 문자열
overflow 긴 문자열에서 버튼/카드 깨짐
concatenation 문법이 깨지는 문자열 조합
missing key fallback text 노출
bidi 문제 RTL에서 punctuation/number 방향 문제

release 전 핵심 flow는 pseudo locale에서 한 번 이상 확인합니다.


6. RTL 지원

왜 중요한가: 아랍어/히브리어 등 RTL 언어는 단순 텍스트 방향뿐 아니라 메뉴 위치, 아이콘 화살표, 모션 방향, 키보드 포커스 순서까지 영향을 줍니다. 뒤늦게 대응하면 거의 모든 컴포넌트를 재작업해야 합니다.

영역 기준
Layout left/right보다 logical property 사용
Icon 방향성이 있는 아이콘은 mirror 기준 정의
Motion slide/transition 방향 검토
Focus keyboard 이동 순서 확인
Data 전화번호, 날짜, 통화, 주소 포맷 locale별 처리

RTL은 단순히 dir="rtl"을 붙이는 작업이 아닙니다. 디자인 시스템 토큰과 컴포넌트 레벨에서 지원해야 합니다.

6.1 RTL 전환 결정 트리

flowchart TD
  PAGE([페이지 진입]) --> Q1{현재 locale이<br/>RTL 언어?}
  Q1 -->|아니오| LTR[dir=ltr 유지]
  Q1 -->|예| Q2{디자인 시스템이<br/>logical property 채택?}
  Q2 -->|아니오| BLOCK_RTL[RTL 비활성화<br/>+ 디자인 부채로 등록]
  Q2 -->|예| SET_DIR[html dir=rtl 적용]
  SET_DIR --> Q3{방향성 아이콘<br/>존재?}
  Q3 -->|예| MIRROR[mirror 규칙 적용<br/>화살표/back 버튼]
  Q3 -->|아니오| Q4
  MIRROR --> Q4{모션/슬라이드<br/>존재?}
  Q4 -->|예| FLIP_MOTION[방향 반전<br/>slide/transition]
  Q4 -->|아니오| Q5
  FLIP_MOTION --> Q5{숫자/날짜/통화<br/>locale별 포맷 적용?}
  Q5 -->|아니오| FORMAT[Intl API 적용]
  Q5 -->|예| KBD
  FORMAT --> KBD{키보드 포커스<br/>순서 검증?}
  KBD -->|아니오| TEST[RTL 키보드 테스트 추가]
  KBD -->|예| READY[RTL 정식 지원]
  TEST --> READY
  LTR --> READY

6.2 i18n 상태 다이어그램

stateDiagram-v2
  [*] --> NotPlanned: 신규 기능
  NotPlanned --> KeyDraft: 메시지 키 추출
  KeyDraft --> SourceReady: en 기준 작성
  SourceReady --> Translating: 번역 요청 송부
  Translating --> ICUFail: ICU 오류
  Translating --> PlaceholderMismatch: placeholder 불일치
  ICUFail --> SourceReady: 수정
  PlaceholderMismatch --> SourceReady: 수정
  Translating --> Reviewed: 사람 번역 검수
  Reviewed --> PseudoSmoke: pseudo-loc 검사
  PseudoSmoke --> Overflow: UI 깨짐
  Overflow --> KeyDraft: 키/UI 조정
  PseudoSmoke --> RTLSmoke: RTL 대상이면
  PseudoSmoke --> Released: RTL 비대상이면
  RTLSmoke --> Released
  Released --> Deprecated: 키 미사용 90일+
  Deprecated --> [*]: 정리 PR

비유: RTL 지원은 거울 방에서 작업하는 것과 같습니다. 좌우 개념을 직접 박지 말고, "시작쪽(inline-start)/끝쪽(inline-end)"이라는 추상 좌표를 사용해야 거울 안에서도 의미가 유지됩니다.


7. SEO와 라우팅

항목 기준
URL locale이 안정적으로 드러나는 URL 구조
Canonical 중복 URL 정리
Hreflang 지역/언어 대체 페이지 연결
Metadata title, description, Open Graph 번역
Sitemap locale별 URL 포함
Redirect 자동 redirect가 crawler 접근을 막지 않도록 설계

검색 노출이 중요한 페이지는 클라이언트에서만 번역하지 말고, 서버/빌드 단계에서 localized metadata를 제공해야 합니다.


8. 성능 기준

왜 중요한가: 글로벌 제품에서 locale 데이터는 가장 빠르게 비대해지는 자산입니다. 초기에 lazy 로딩 전략을 박지 않으면, locale 추가마다 LCP가 선형으로 악화됩니다.

항목 기준
번역 번들 현재 locale과 route에 필요한 메시지만 로드
폰트 locale별 subset, fallback, preload 최소화
날짜/숫자 포맷 표준 Intl API 우선
캐시 locale별 cache key와 fallback 명확화
hydration 서버/클라이언트 locale 불일치 방지

모든 locale 번역을 초기 번들에 넣으면 글로벌 제품일수록 성능이 급격히 나빠집니다.

8.1 번역 번들 로딩 전략

flowchart LR
  REQ[요청] --> SSR[SSR locale 판별]
  SSR --> CORE[core 메시지<br/>nav/footer/error]
  SSR --> ROUTE[route별 메시지<br/>현재 경로만]
  CORE --> HYDRATE[hydration]
  ROUTE --> HYDRATE
  HYDRATE --> CLIENT[클라이언트 라우팅]
  CLIENT -->|새 경로 진입| LAZY[lazy chunk 로드]
  LAZY --> CACHE[(locale별 cache)]
  CACHE -.fallback miss.-> CORE

9. 체크리스트

  • [ ] locale 결정 우선순위가 문서화되어 있는가
  • [ ] 메시지가 plural/select/date/number 포맷을 지원하는가
  • [ ] 누락/미사용 키와 placeholder 불일치가 CI에서 잡히는가
  • [ ] pseudo-localization으로 overflow와 hard-coded text를 확인하는가
  • [ ] RTL locale에서 layout, icon, focus, motion을 검증하는가
  • [ ] hreflang/canonical/metadata/sitemap이 locale별로 생성되는가
  • [ ] AI 번역 결과를 용어집, placeholder, 사람 검토로 검증하는가

10. 제외한 벤더 종속 항목

공통 개발 가이드에는 특정 번역 SaaS, 특정 AI 번역 모델, 특정 알림 도구, 특정 OTA 번역 SDK, 특정 배포 플랫폼의 워크플로우를 표준으로 포함하지 않습니다. 이 문서에는 어떤 국제화 도구를 쓰더라도 유지되어야 하는 locale, message format, QA, RTL, SEO, 성능 기준만 남깁니다.


실무 적용 가이드

언제 이 문서를 펼칠까

  • 문자열 길이, 복수형, RTL, locale routing이 뒤늦게 문제될 때
  • AI 번역 결과가 placeholder나 법무 문구를 깨뜨릴 때
  • locale bundle이 성능을 악화시킬 때

적용 순서

  1. locale 결정 규칙과 fallback 순서를 정한다.
  2. ICU message로 plural/select/placeholder를 구조화한다.
  3. 번역 키, source text, screenshot/context를 함께 관리한다.
  4. pseudo-localization과 RTL smoke를 핵심 flow에 적용한다.
  5. message compile, placeholder diff, locale SEO를 CI에서 확인한다.

함께 두는 파일

  • feature별 메시지, screenshot context, test를 기능 폴더에 둔다.
  • 전역 navigation/공통 컴포넌트 메시지만 shared i18n에 둔다.
  • locale route metadata는 SEO 문서와 연결한다.

흔한 실수

  • 문장 조각을 이어 붙인다.
  • placeholder 검증 없이 번역을 merge한다.
  • RTL에서 margin/padding 방향을 하드코딩한다.
  • 모든 locale 메시지를 초기 번들에 넣는다.

PR 완료 기준

  • [ ] message compile이 통과한다.
  • [ ] placeholder/plural 검증이 있다.
  • [ ] pseudo-loc/RTL 핵심 flow가 통과한다.
  • [ ] locale bundle 영향이 확인되었다.

추천 항목 실행 우선순위 매핑

  • P1(7일 내) — locale routing, ICU message, fallback, RTL smoke 중 하나를 작은 변경 1건에 적용하고 증거(message compile)를 남긴다.
  • P2(30일 내) — 국제화 기준을 팀 템플릿, 체크리스트, CI 중 한 곳에 고정한다.
  • P3(90일 내) — missing key, overflow defect, locale SEO mismatch 추이를 보고 기준을 유지할지 조정할지 결정한다.
  • 완료 기준 — i18n 오너가 증거와 철회 조건을 확인했다는 기록을 남긴다.

추천 항목 실행 체크리스트

  • [ ] 1단계(7일) : locale routing, ICU message, fallback, RTL smoke 적용 대상을 1개로 좁힌다.
  • [ ] 2단계(30일) : 증거(message compile, placeholder diff, pseudo-loc screenshot, hreflang 검사)를 PR, ADR, 회고 중 한 곳에 연결한다.
  • [ ] 3단계(60일) : missing key, overflow defect, locale SEO mismatch가 기준 안에 들어왔는지 확인한다.
  • [ ] 문제 대응 : 미달성 사유와 다음 조치, 중단 여부를 같은 기록에 남긴다.

추천 항목 실행 운영 규칙

  • 실행 게이트 : 번역 전에 변수, plural, fallback 규칙이 구조화됐는지 확인한다.
  • 승인 체계 : i18n 오너가 영향 범위와 rollback 담당자를 적용 전에 확인한다.
  • 재개 조건 : pseudo-loc/RTL smoke와 SEO metadata가 통과하면 locale을 공개한다.
  • 정지 조건 : placeholder 깨짐이나 hard-coded text가 남으면 release를 막는다.
  • 리스크 점수 : 지원 locale 수, 법적 문구, RTL 여부로 산정한다.
  • 리더 승인자 : 글로벌 UX 리드가 최종 승인 책임을 맡는다.
  • 승인 역할 : 국제화 작성자, 검토자, 운영 확인자를 분리해 기록한다.
  • 재평가 주기 : locale 추가와 copy 변경 때마다 QA 샘플을 갱신한다.