안녕하세요! K-POP 데몬헌터스의 인기와 APEC의 영향력 덕분에, 전 세계에서 한국어가 점점 더 주목받고 있습니다. 그에 맞춰 국내 웹사이트들도 빠르게 국제화(i18n)를 도입하고 있는데요.
오늘은 React 프로젝트에 다국어 기능을 적용하면서 겪는 고통과, 이를 2분 만에 완전히 자동화하는 방법을 소개해보려 합니다.
기존 프로젝트에 국제화를 붙여보고 싶지만 “복잡한 설정 때문에 엄두가 안 난다…” 하시는 분들, 또는 가볍게 다국어 지원을 시험해보고 싶은 분들께 특히 추천드립니다.
라면 물 올리는 시간보다 짧습니다! 🍜 지금 바로 시작해보시죠.
프론트에서 대부분의 국제화 처리는 i18n이 들어가는 라이브러리들이 존재합니다.
이들은 대부분 아래처럼 작성해야합니다
const { t } = useTranslation({lng})
//jsx
<div>{t("안녕하세요")}</div>
t가 래핑된 텍스트에 한해서 라이브러리로 텍스트를 변경하는것입니다.
누구나 공감하는 i18n 적용 과정
수동으로 국제화를 관리해야 하는 경험 있으신가요?
500개의 파일에 하드코딩된 한국어 텍스트를 전부 t() 함수로 바꿔야 하는 상황.
하나하나 파일을 열어서 “환영합니다”를 찾고, {t('환영합니다')}로 바꾸고, useTranslation import를 추가하고…
페이지마다 7시간 이상이 걸립니다. 그리고 이건 단순히 시간 문제만이 아닙니다.
Props Drilling의 악몽
Next.js에서 next-i18next를 사용 그리고 주소에 lng를 사용한다면 이런 코드를 작성하게 됩니다:
// 페이지에서 시작해서...
export default function HomePage({ params }: { params: { lng: string } }) {
return <Layout lng={params.lng} />;
}
// Layout을 거쳐...
export default function Layout({ lng }: { lng: string }) {
return <Header lng={lng} />;
}
// Header를 거쳐...
export default function Header({ lng }: { lng: string }) {
return <Navigation lng={lng} />;
}
// 마침내 5단계를 거쳐 도착!
export default function Navigation({ lng }: { lng: string }) {
const { t } = useTranslation(lng);
return <nav>{t('home')}</nav>;
}
컴포넌트가 150개라면? 150번 수정해야 합니다. 😫
진짜 지옥은 따로 있습니다: Alert과 Toast
UI 텍스트는 그래도 눈에 보이니까 찾기라도 쉽습니다. 하지만 이런 코드는 어떤가요?
try {
await api.updateUser();
toast.success("업데이트 완료!");
} catch {
alert("에러가 발생했습니다.");
}
이런 메시지들은 비즈니스 로직 곳곳에 숨어있습니다:
- 커스텀 훅 안에
- 서비스 레이어에
- 에러 핸들링 유틸에
- API 래퍼에
마치 지뢰처럼 흩어져 있어서, “대체 어디에 박아놨더라…” 하며 파일을 뒤지게 됩니다.
하드코딩을 t()로 감싸면 끝일까요?
.
.
.
.
.
정답은 !! “Nope!!!”
보통 “i18n을 적용한다”라고 하면 문자열을 t()로 감싸는 정도만 떠올리기 쉽습니다.
하지만… 그건 전체 작업의 30% 정도에 불과합니다. 진짜 고통은 그다음에 찾아옵니다.
- t() 래핑 → 끝이 아닙니다
하드코딩된 “환영합니다” 텍스트를 이렇게 감싸기만 하면 정말 끝일까요?
<h1>{t("환영합니다")}</h1>
아닙니다. 그때부터 시작입니다.
- JSON(번역 리소스) 관리
다음 단계는 t() 안에 들어가는 문자열을 ko.json, en.json 같은 번역 파일에 넣는 일입니다.
{
"환영합니다": "환영합니다"
}
문제는…
- 매 파일 열어서 key 넣고
- 기존 key와 충돌하는지 확인하고
- 누락된 key는 없는지 확인해야 하고
→ 귀찮습니다…..
- 번역 (가장 힘듦)
한국어만 넣었다고 끝이 아닙니다. 영어·일본어·중국어… 다 넣어야 합니다.
“영어 잘하면 좋겠지만…” 대부분의 경우 프론트엔드 엔지니어가 대신 번역해야 합니다.
특히 내부에서 i18n 작업을 전적으로 프론트에 맡기는 팀이라면, 영문 번역까지 엔지니어가 처리해야 하기도 합니다.
저희 팀도 실제로 그랬습니다. 한국어 → 영어 번역까지 진행했습니다.
이게 한두 줄이면 괜찮습니다. 하지만 수백 줄이라면… 단순 번역이 아니라 의미와 맥락을 고려한 의역이 필요하기 때문에 시간을 태워 넣게 됩니다. 😩
- 적용 확인
그리고 다시 돌아와서…
- 올바르게 적용되었는지
- UI가 깨지진 않는지
- 줄바꿈이 망가지진 않았는지
- 문맥이 자연스러운지
눈으로 다시 확인해야 합니다.
즉, 단순 치환이 아니라 QA 과정이 반드시 따라옵니다.
하드코딩을 t()로 감싸는 건 30% 완료일 뿐, 남은 70%는 “번역 & 관리”입니다.
그래서 i18n은 단순 문자열 래핑이 아니라 번역 워크플로우 전체를 어떻게 자동화하느냐가 진짜 핵심입니다.
- key 자동 추출
- JSON 자동 병합
- 누락 key 감지
- 번역 자동화 (Google Translate · DeepL)
- Google Sheets/Notion 연동
- QA 보조
- 타입 안전성 지원
이런 요소가 있어야 사람 손이 닿는 부분을 최소화할 수 있고, 기술 부채가 터지는 걸 막을 수 있습니다.
완전 자동화
이 모든 문제를 해결하는 방법이 있습니다. Babel AST를 사용한 지능형 코드 변환입니다.

CLI를 통한 변환
// Before: 하드코딩
function Welcome() {
return <h1>환영합니다</h1>;
}
// After: 자동 변환 (1초 소요)
import { useTranslation } from 'react-i18next';
function Welcome() {
const { t } = useTranslation();
return <h1>{t('환영합니다')}</h1>;
}
기존의 페이지 하나 수작업 7시간 → 모든 페이지 자동화 3분
i18nexus-tools: 5가지 강력한 도구
i18nexus-tools는 다국어 작업을 완전히 자동화합니다.
1️⃣ i18n-sheets init: 10초 만에 프로젝트 설정
npm install -g i18nexus-tools (Global로 설치!)
// 원하는 프로젝트에 들어간후
npx i18n-sheets init
대화형 인터페이스로 설정시 완벽한 구조가 자동으로 생성됩니다:
src/
├── i18n/
│ ├── translations/
│ │ ├── ko.json
│ │ ├── en.json
│ │ └── ja.json
│ └── i18n.ts
└── i18nexus.config.json
i18nexus.config.json 설정
프로젝트 설정 파일로, 모든 i18nexus-tools 명령어가 이 설정을 참조합니다:
{
"languages": ["en","ko"], // 지원할 언어 모두 입력
"defaultLanguage": "en", // 기본언어 선택
"localesDir": "./locales", // [언어].json 이 위치한 폴더
// wrapper가 참조할 디렉토리 구조 패턴 기본은 src
"sourcePattern": "src/**/*.{js,jsx,ts,tsx}",
// useTranslation을 참조할 위치
"translationImportSource": "i18nexus",
// 추가사항 구글 시트 연동시
"googleSheets": {
"spreadsheetId": "",
"credentialsPath": "./credentials.json",
"sheetName": "Translations"
}
}
2️⃣ i18n-wrapper: 지능형 코드 변환
가장 강력한 기능입니다. 하드코딩된 텍스트를 자동으로 t() 함수로 변환해줍니다.
npx i18n-wrapper
지능적인 변환 예시
JSX 텍스트:
// Before
<div>
<h1>환영합니다</h1>
<p>서비스를 시작하세요</p>
</div>;
// After (2초 소요)
const { t } = useTranslation();
<div>
<h1>{t("환영합니다")}</h1>
<p>{t("서비스를 시작하세요")}</p>
</div>;
템플릿 리터럴도 자동으로:
// Before
const message = `사용자 ${count}명이 접속 중`;
// After
const message = t("사용자 {{count}}명이 접속 중", { count });
동적 데이터 [대부분의 경우 API데이터] 자동으로 스킵:
function UserCard({ userName }) {
return (
<div>
{/* ❌ 변환 안 함 (props) */}
<h2>{userName}</h2>
{/* ✅ 변환 (정적 텍스트) */}
<button>{t("프로필 보기")}</button>
</div>
);
}
3️⃣ i18n-extractor: 번역 키 자동 추출
코드에서 모든 t() 호출을 찾아 JSON 파일을 자동으로 생성합니다.
npx i18n-extractor
// 자동 생성된 ko.json
{
"환영합니다": "환영합니다",
"서비스 설명": "서비스 설명",
"시작하기": "시작하기"
}
// 자동 생성된 en.json
{
"환영합니다": "",
"서비스 설명": "",
"시작하기": ""
}
기본적으로 한국어 지원 라이브러리기에 현재 작성된 txt를 ko.josn에 추가합니다
value 또한 기본적으로 한국어로 설정됩니다.
4️⃣ Google Sheets 연동: 번역가와 실시간 협업
이제 번역가와 JSON 파일을 주고받을 필요가 없습니다. Google Sheets로 실시간 협업이 가능합니다!
# 업로드 (자동 번역 포함)
i18n-upload --auto-translate
# 번역가 작업 (Google Sheets에서)
# 다운로드
i18n-download
# 강제 다운로드 (로컬 변경사항 무시)
i18n-download-force
auto-translate옵션을 사용하면 구글의 공식 번역 엔진으로 자동 번역까지 해줍니다:
| Key | 한국어 | 영어 |
|-----------|------------|----------------------------------------|
| 환영합니다 | 환영합니다 | =GOOGLETRANSLATE(B2,"ko","en") |
번역가는 Sheets에서 직접 수정하면 되고, 여러분은 npx i18n-download만 실행하면 끝입니다!
[번역을 llm으로 하면 성능이 좋지만 토큰이 아깝다면 추천드립니다..! ]
기본적으로 extractor, download, upload, wrapper 명령들은
이미 존재하는 번역 키를 비교해 기존 값을 유지하는 보수적 방식으로 동작합니다.
즉, 충돌 가능성이 있는 키를 함부로 덮어쓰지 않습니다.
만약 강제로 덮어쓰기가 필요하다면
- —force 옵션을 통해 진행할 수 있습니다.
모든 i18n 라이브러리와 호환됩니다
i18nexus-tools는 범용 도구입니다. 어떤 라이브러리를 사용하든 동작합니다:
✅ react-i18next ✅ next-i18next ✅ react-intl ✅ i18next (바닐라)
설정 파일에서 사용할 위치만 지정하면 됩니다!
{
...
"sourcePattern": "src/**/*.{js,jsx,ts,tsx}",
"translationImportSource": "react-i18next", // 원하는 임포트 위치만 사용
}
현재는 아래와 같은 형태의 라이브러리만 지원됩니다.
const { t } = useTransaltion()
→ 라이브러리 명만 작성해도 되도록 기능 수정작업 중입니다.
→ 원하시는 라이브러리 명을 댓글에 작성해주시면 감사하겠습니다! 우선작업하겠습니다.
i18nexus: 완벽한 통합 솔루션
i18nexus-tools는 범용 자동화 도구지만, i18nexus 라이브러리와 함께 사용하면 훨씬 더 강력합니다.
Props Drilling 완전 제거
// ❌ next-i18next
function Page({ params }: { params: { lng: string } }) {
return <Layout lng={params.lng} />;
}
// ✅ i18nexus
function Page() {
return <Layout />; // 👈 lng 파라미터 불필요!
}
Next.js SSR 완벽 지원
// ✅ i18nexus: 간단한 Server Component
import { getServerTranslation } from "i18nexus/ssr";
import { translations } from "@/i18n/i18n";
async function Component() {
const { t } = await getServerTranslation(translations);
return <p>{t("text")}</p>;
}
TypeScript 자동 지원
const { t } = useTranslation();
t("welcome"); // ✅ 자동완성
t("welcom"); // ❌ 컴파일 에러!
// ~~~~~~
// 'welcom'은 존재하지 않는 키
적용 FLOW
이미 완성된 프로젝트에서 특히 빠르게 적용이 가능합니다.
# 1. 설치 (30초)
npm install i18nexus
npm install -g i18nexus-tools
# 2. 초기화 (10초)
i18n-sheets init
# 3. Provider 적용 (10초)
# app/layout.tsx에 I18nProvider 추가
# 4. 코드 작성
# 일반적인 React 코드로 작성
# 5. 자동 변환 (1초)
i18n-wrapper
# 6. 번역 키 추출 (1초)
i18n-extractor
# 7. Google Sheets 업로드 (자동 번역 포함)
i18n-upload --auto-translate
# 8. 번역 완료 후 다운로드
i18n-download
# 완료! 총 2분 소요
이미 완성된 프로젝트에서도 영어 지원을 하는데 걸리는 시간 2분!!!!
수작업으로 진행시 7시간 걸리던 다국어 작업을 2분으로 줄여보세요.
NO MORE HARD!!!!
더 이상 하드코딩을 하나하나 찾아 헤매지 마세요.
더 이상 props drilling에 시달리지 마세요.
더 이상 번역가와 JSON 파일을 주고받지 마세요.
i18nexus-tools와 i18nexus가 모든 걸 자동화해드립니다.
🎮 라이브 데모