i18n
브라우저 화면과 서버, 알림과 이메일이 같은 번역과 날짜 표기 규칙을 쓰게 한 다국어 패키지입니다. 번역 목록에 없는 문구를 쓰면 코드를 쓰는 단계에서 바로 드러납니다.
- 2026.04 ~ 현재
- Firstage
- 설계와 구현 (1인)

핵심 가치
지금 화면을 보는 사람의 언어와 메시지를 받을 사람의 언어를 서버에서 나눠 다뤄, 다른 사람에게 가는 푸시 알림도 받는 사람의 언어로 나갑니다.
성과
- ROUND, Firstage 홈페이지, Journey 앱과 서버, 이메일 템플릿에서 사용
- 화면(React), 웹 서버(Next.js), 앱 서버(Node)가 같은 번역 핵심을 공유
- 번역 목록에 없는 문구를 쓰면 바로 오류로 알려 줌
- 받는 사람의 언어로 고르는 푸시 문구를 한국어, 일본어, 영어로 검증
기술 스택
배경
Firstage의 서비스는 한국어, 영어, 일본어를 함께 지원하고, 같은 문구가 브라우저 화면, Next.js 서버 렌더링, NestJS 서버의 알림과 이메일에 두루 쓰입니다. 실행 환경마다 번역 방식이 달라지면 키 누락과 언어 혼동이 생기기 쉬워서, 번역과 포맷을 한 코어로 모으고 실행 환경별 어댑터만 나눈 패키지를 만들었습니다.
결정과 구현
- 코어는 어디서나 돌고, React(클라이언트), Next.js App Router(서버), Node(NestJS와 Express) 어댑터를 별도 진입점으로 나눠 필요한 것만 번들에 들어가게 했습니다.
- 번역 키는 가져온 JSON 카탈로그에서 타입으로 추론해, 없는 키를 쓰면 타입 검사에서 드러납니다. Intl 포맷터는 옵션별로 캐시합니다.
- 지금 화면을 보는 사람의 언어와 특정 언어로 번역해야 하는 메시지를 다른 문으로 나눴습니다. 서버가 보내는 메시지는 보낸 사람이 아니라 받는 사람이 읽기 때문에, 서버 어댑터에는 언어를 명시하는 forLocale을 따로 두었습니다.
- React에는 언어를 명시하는 문을 일부러 두지 않았습니다. 한 화면은 한 사람을 위해 그려지므로 두 번째 언어가 필요하면 Provider를 하나 더 둡니다. 앱에 있던 우회 함수가 Provider와 어긋났던 경험에서 나온 결정입니다.
- 언어 협상과 Accept-Language 해석은 워크스페이스의 국제화 기본 패키지 하나에서 가져옵니다.
현재 상태
ROUND, Firstage 홈페이지와 블로그, Journey 앱과 서버, 사내 Dashboard, 이메일 템플릿이 이 패키지로 다국어를 처리합니다. Journey 서버의 푸시 알림은 받는 사람이 저장한 언어로 문구를 고르고, 언어 정보가 없으면 영어로 보냅니다.
