다국어 사이트 삽질 기록: 인터페이스 언어 ≠ 글 언어
이번에 사이트에 다국어를 추가하면서, 처음에는 Footer에 언어 전환 버튼만 달고 AI로 글을 번역하면 끝이라고 생각했다. 막상 해보니 문제가 생각보다 많았다.
가장 핵심적인 점은: 인터페이스 언어, 테마 설정 언어, 글 본문 언어를 같은 개념으로 섞으면 안 된다는 것.
- 인터페이스 언어: 내비게이션, Footer, 버튼, 날짜 등 UI 문구.
- 테마 설정 언어: Hero 설명, 한 줄 문구, Footer의 '소개 / 더보기 / 연락처' 같은 테마 필드.
- 글 언어: 한 글이 실제로 존재하는 본문 버전.
일본어 인터페이스만 있는데 글이 일본어 번역본이 없다면, 그 글을 일본어 글인 척 꾸밀 수도 없고 링크가 그냥 404가 되게 둘 수도 없다.
이번에 겪은 문제들
처음에는 언어 전환 시 언어 코드를 URL에 직접 넣었다. 예를 들어 /ja/posts/...처럼. 그런데 모든 글에 일본어 버전이 있는 건 아니다 보니, 굉장히 어긋난 경험이 생겼다:
- 사용자가 일본어 인터페이스로 전환;
- 중국어로만 된 글을 클릭;
- 페이지가 일본어 라우트로 이동;
- 일본어 콘텐츠를 찾을 수 없어 결국 404.
또 다른 문제는, 시스템이 글 내용을 자동으로 영어로 인식한 경우였다. 그러면 발행이나 알림 이동 시 영어 경로로 들어가게 된다. 게다가 백엔드에서 영어만 번역 대상으로 설정해 두면, 영어 원문은 더 이상 중국어로 번역되지 않아서 중국어 사이트에도 볼 수 있는 버전이 없어졌다.
번체 중국어도 전형적인 문제를 드러냈다: zh-TW가 잘못해서 zh로 정규화된 것. 겉보기엔 그냥 언어 코드 하나의 세부 사항일 뿐인데, 결과적으로 테마 설정, 글 조회, API 검증에 영향을 줬다:
theme/yohaku.zh-TW는 분명히 존재하는데;- 집계 인터페이스는
theme/yohaku.zh를 찾으러 가고; - 그래서 Footer가 간체 중국어로 폴백되고;
- 나중에 프론트엔드가
zh-TW로 이동할 수 있게 되어도, 인터페이스가 두 자리 언어 코드만 허용해서 요청을 거부했다.
현재 적용 중인 방식
사이트는 다섯 가지 인터페이스 언어를 유지한다:
백엔드 AI 번역의 목표 언어도 이 다섯 가지로 설정했다.
하지만 모든 글에 다섯 개의 사본을 만드는 건 아니고, 다음과 같이 처리한다:
예를 들어:
| 원문 언어 | 자동 생성되는 번역본 |
|---|---|
간체 중국어 zh | 번체, 영어, 일본어, 한국어 |
영어 en | 간체, 번체, 일본어, 한국어 |
번체 중국어 zh-TW | 간체, 영어, 일본어, 한국어 |
이렇게 하면 원문을 중복 번역하지 않으면서도, 모든 사이트 언어에 실제 콘텐츠 버전이 보장되어 전환 후 404가 나는 일을 피할 수 있다.
원문 언어는 작성자가 선언해야 한다
더 이상 시스템이 본문을 보고 글 언어를 자동으로 추측하게 두지 말자.
이제 글 편집기에 '콘텐츠 언어 / 원문 언어' 필드가 있어야 한다. 작성자가 발행할 때 실제 원문 언어를 선택하고, 특별히 선택하지 않으면 기본값은 간체 중국어다.
이것은 중요하다. 원문 언어가 영향을 주기 때문이다:
- 자동 번역 시 어떤 언어를 제외할지;
- 번역 작업의 콘텐츠 해시;
- 이후 글을 수정할 때 어떤 번역본을 다시 생성해야 할지;
- 알림, 이동, 콘텐츠 가용성 판단.
AI는 번역 과정에서 언어를 관찰할 수 있지만, 작성자가 선언한 원문 언어를 몰래 덮어써서는 안 된다.
테마 설정도 언어별로 오버라이드
간체 중국어 테마 설정을 기본 설정으로 두고, 다른 언어는 번역이 필요한 필드만 유지하면 된다. 예를 들어:
색상, 레이아웃, 폰트 같은 시각적 설정은 복사할 필요가 없다. 이렇게 하면 나중에 테마 스타일을 바꿀 때 기본 설정만 수정하면 된다.
번체 중국어는 통일된 canonical code를 사용해야 한다:
어떤 곳에서는 zh-TW라고 쓰고, 다른 곳에서는 zh로 접어서는 안 된다. 그렇지 않으면 테마 오버라이드, 글 번역, API 조회가 각각 다른 결과를 얻게 된다.
여전히 주의해야 할 경계
다국어 번역본 자동 생성의 전제는: 번역 작업이 최종적으로 성공하는 것.
특정 언어의 번역이 실패하면, 백엔드 작업 센터에서 확인하고 재시도할 수 있어야지, 프론트엔드에서 조용히 빈 페이지가 나오게 해서는 안 된다. 이미 존재하는 오래된 글은 설정 완료 후 수동으로 전체 번역 작업을 실행하면 된다. 이후 글을 수정·저장할 때 시스템이 만료되거나 누락된 번역본을 증분 방식으로 채워 넣으면 된다.
이번에 가장 크게 배운 점은: 다국어는 URL에 접두사를 붙이는 것도, 단순한 번역 버튼도 아니라는 것.
명확한 계약이 필요하다:
콘텐츠, 인터페이스, 테마 세 계층이 동일한 정규화된 언어 코드를 사용하기만 하면, 다국어 경험이 전환 중에 갑자기 끊기지 않는다.
다국어 번역의 함정