「今すぐ始める」는 일본어가 아니었다
같은 버튼, 다른 언어 — 번역으로는 닿지 않는 30%에 대하여
깨달음: "다른 나라에 집을 짓는 건, 설계도를 번역하는 게 아니라 그 동네의 바람 방향을 이해하는 일이다."
한국어 사이트가 돌아가고 있으니까, 일본어 사이트는 금방 만들 수 있을 거라고 생각했다. 같은 집을 하나 더 짓는 거니까. 벽지 색만 바꾸면 되지 않을까.
저녁에 노트북을 열고 작업을 시작했다. 계획은 단순했다. 한국어 사이트를 복제하고, 텍스트를 일본어로 바꾸고, 배포한다. 이틀이면 될 줄 알았다.
첫 번째 벽은 기술적인 것이었다.
다국어 사이트를 만들려면 i18n이라는 것을 설정해야 한다. internationalization의 약자인데, "i"와 "n" 사이에 18글자가 있어서 i18n이다. 누가 지은 이름인지 모르겠지만, 개발 세계에는 이런 이름들이 많다.
Next.js에서 다국어 라우팅을 설정하는 건 next-intl이라는 라이브러리를 쓴다. /ko로 접속하면 한국어, /ja로 접속하면 일본어가 나오게 하는 것이다. 설명만 들으면 간단하다.
하지만 이걸 기존 사이트에 얹으려고 하니, 라우팅이 깨졌다. 페이지가 안 나오거나, 나와도 한국어가 그대로 나오거나, 404가 뜨거나. 빨간 글씨와의 재회였다. 관제탑에 에러를 보내고, 돌아온 답을 적용하고, 다른 에러가 나오고. EP.05의 토글 사건과 비슷한 순환이 시작됐다.
결국 라우팅 문제는 해결됐다. 하지만 해결되고 나니, 두 번째 벽이 나타났다.
한국어 사이트의 컴포넌트 — 화면을 구성하는 부품들 — 내부에 한국어가 직접 박혀 있었다. 번역 파일에서 텍스트를 가져오는 게 아니라, 코드 안에 "무료로 시작하기", "채널을 등록하세요" 같은 한국어 문장이 그대로 적혀 있었다.
이게 왜 문제냐면, 이 상태로는 번역 파일을 아무리 바꿔도 화면에 반영이 안 된다. 번역 파일이 말하는 건 "여기에 일본어를 넣어줘"인데, 코드 자체가 "여기에는 한국어를 넣어"라고 고정해버린 것이다.
한국어 사이트를 만들 때는 이게 문제가 아니었다. 어차피 한국어만 쓸 거였으니까. 하지만 두 번째 언어를 추가하는 순간, "처음부터 다국어를 고려하지 않은 구조"라는 사실이 드러났다. EP.02에서 V2→V3 리팩터링을 겪었던 것과 같은 패턴이었다.
컴포넌트를 하나하나 열어서, 하드코딩된 한국어를 번역 키로 교체하는 작업을 했다. "무료로 시작하기"를 t('cta.start_free')로 바꾸고, 번역 파일에 한국어와 일본어를 각각 넣는 식이다. 지루하지만 필요한 작업이었다.
그렇게 기술적 문제와 구조적 문제를 해결하고, 일본어 텍스트가 화면에 나오기 시작했을 때 — 세 번째 벽이 나타났다.
이건 기술이 아니라 감각의 문제였다.
화면을 보고 있는데, 뭔가 이상했다. 일본어가 나오고 있다. 문법도 맞다. 단어도 틀리지 않았다. 하지만 이 사이트를 일본 사람이 보면 — 이건 일본인을 위해 만들어진 서비스가 아니라, 해외 서비스를 번역해서 가져온 것처럼 보일 거라는 생각이 들었다. 전문성이 떨어져 보였다.
이유를 찾으려고 했다. 문장은 맞는데 왜 어색한가.
한국어 CTA가 "지금 시작하기"였다. 이걸 일본어로 번역하면 「今すぐ始める」가 된다. 의미는 같다. 하지만 일본 SaaS 사이트들이 실제로 쓰는 표현을 보면 다르다. 더 정중하고, 더 설명이 많고, 더 조심스럽다. 「まずは無料でお試しください」 — "우선 무료로 체험해보세요"라는 뉘앙스. 한국어에서는 "시작하기"가 자연스럽지만, 일본어에서는 "체험해보세요"가 자연스럽다.
UI 텍스트만 그런 게 아니었다. 기능을 설명하는 방식도 달랐다. 한국어 사이트에서는 기능을 세 줄로 요약하고 바로 CTA 버튼을 배치했다. 하지만 일본 사이트들은 기능 하나를 설명할 때 더 많은 맥락을 제공한다. 왜 이 기능이 필요한지, 어떤 상황에서 쓰는지, 다른 것과 뭐가 다른지. 텍스트 양이 한국어보다 30% 이상 많아지는 경우가 흔했다.
마스터 플랜에 이미 적혀 있었다. "번역 ≠ 로컬라이제이션." "일본은 정중함 + 상세 설명 + 높은 완성도. UI 텍스트가 한국보다 30%+ 길어질 수 있음." 읽었을 때는 이해했다고 생각했다. 하지만 실제로 화면을 보면서 "이건 번역이지, 일본 서비스가 아니야"라고 느끼는 건 다른 종류의 이해였다.
나는 일본어를 비즈니스 수준으로 할 수 있다. 이건 AI 번역으로 대체할 수 없는 자산이라고 마스터 플랜에도 적혀 있다. 하지만 "일본어를 할 수 있다"는 것과 "일본인이 편하게 느끼는 서비스를 만들 수 있다"는 것은 다른 능력이었다. 전자는 언어 능력이고 후자는 문화적 감각이다.
결국 번역 파일을 전면 재작업했다. 한국어를 일본어로 바꾸는 게 아니라, 일본어 사이트에 처음부터 어떤 말이 있어야 하는지를 생각하면서 다시 썼다. 같은 기능이지만 설명 방식이 달라졌다. 같은 버튼이지만 문구가 달라졌다. 같은 구조이지만 텍스트의 양과 톤이 달라졌다.
시간이 예상보다 많이 걸렸다. "이틀이면 될 줄 알았다"에서 시작했는데, 이틀이 아니었다.
하지만 이 과정에서 하나를 확실히 배웠다. 다른 나라에 서비스를 내놓는 건, 같은 집을 하나 더 짓는 게 아니다. 그 동네의 기후와 관습에 맞는 다른 집을 짓는 것이다. 설계도를 번역하는 게 아니라 새로 그리는 것이다.
「今すぐ始める」는 문법적으로 완벽한 일본어다. 하지만 일본어가 아니었다.
🔧 이 에피소드의 기술 용어 해설
i18n (Internationalization) 소프트웨어를 여러 언어로 사용할 수 있게 만드는 작업. "internationalization"에서 첫 글자 i와 마지막 글자 n 사이에 18글자가 있어서 i18n이라고 줄여 부른다. 비슷하게 l10n(localization)도 있다.
next-intl
Next.js에서 다국어 사이트를 만들 때 사용하는 라이브러리. /ko로 접속하면 한국어, /ja로 접속하면 일본어가 나오도록 라우팅을 설정해준다.
라우팅 (Routing)
URL에 따라 어떤 페이지를 보여줄지 결정하는 것. 식당 비유로, 손님이 "2번 테이블"이라고 하면 2번으로 안내하는 것. /ja라는 URL이 들어오면 일본어 페이지로 안내하는 것이 라우팅이다.
컴포넌트 (Component) 화면을 구성하는 독립적인 부품. 레고 블록처럼, 헤더 컴포넌트, 버튼 컴포넌트, 카드 컴포넌트를 조합해서 전체 페이지를 만든다.
하드코딩 (Hardcoding) 값을 코드에 직접 고정하는 것. "무료로 시작하기"라는 텍스트를 코드에 직접 적는 것. 반대는 번역 파일이나 설정 파일에서 값을 가져오는 것. 하드코딩된 텍스트는 언어를 바꿀 때 코드 자체를 수정해야 하므로 다국어 대응에 치명적이다.
번역 키 (Translation Key)
번역 파일에서 텍스트를 가져올 때 사용하는 식별자. t('cta.start_free')라고 쓰면, 한국어 파일에서는 "무료로 시작하기", 일본어 파일에서는 「まずは無料でお試しください」를 가져온다. 코드는 하나인데 언어에 따라 다른 텍스트가 나오는 구조.
로컬라이제이션 (Localization, l10n) 단순 번역이 아니라, 현지 문화·관습·기대에 맞게 서비스 전체를 조정하는 것. 같은 CTA 버튼이라도 한국어에서는 "시작하기", 일본어에서는 「まずはお試しください」(우선 체험해보세요)로 뉘앙스가 달라져야 한다. 텍스트뿐 아니라 레이아웃, 설명의 양, 톤까지 포함된다.