Next-Translate 3.0 — Turbopack과 App Router를 위한 i18n 재건
Next-Translate는 Next.js 생태계에서 가장 가벼운 i18n 라이브러리 중 하나다. 그 라이브러리가 1년간의 공백 끝에 3.0을 내놨다. 무엇이 바뀌었고, 왜 지금 이 업데이트가 필요했는지 살펴본다.
왜 1년이나 걸렸나
Next.js 자체가 빠르게 바뀌었다. App Router 안정화, params의 비동기화, Turbopack 전환까지 Next.js 15-16 사이에 상당한 변화가 있었다. 기존 Next-Translate는 이 변화들을 따라잡는 게 쉽지 않았다.
[💡 잠깐! 이 용어는?] i18n (Internationalization): 앱을 여러 언어/지역에서 사용할 수 있게 만드는 작업. "국제화"를 줄여서 i18n이라 부른다 (i와 n 사이 글자 수가 18). 번역 파일 로딩, 날짜/숫자 포맷, RTL 레이아웃 지원 등이 포함된다.
3.0의 핵심 변경사항
Turbopack 지원
Next.js 16이 Turbopack을 기본 번들러로 채택하면서, Webpack 플러그인 기반 라이브러리들이 줄줄이 대응을 해야 했다. Next-Translate도 그 중 하나였다.
3.0은 Turbopack 환경에서도 번역 파일 로딩이 정상 작동하도록 내부 플러그인 구조를 재작성했다. 기존 Webpack 환경과의 하위 호환성은 유지된다. 비유하면 구형 엔진(Webpack)을 쓰던 차에서 신형 전기 모터(Turbopack)로 갈아끼웠는데 계기판과 핸들이 그대로 작동하는 것과 같다.
[💡 잠깐! 이 용어는?] Turbopack: Vercel이 개발한 Rust 기반 번들러. Webpack을 대체하는 것을 목표로 하며, Next.js 16부터 기본 번들러로 전환됐다. 빌드 속도가 Webpack 대비 크게 빠르다.
import nextTranslate from 'next-translate-plugin'
import type { NextConfig } from 'next'
const nextConfig: NextConfig = {
// Turbopack과 함께 동작 (별도 설정 불필요)
}
export default nextTranslate(nextConfig)비동기 params 지원
Next.js 15부터 params와 searchParams가 비동기로 바뀌었다. 기존 동기 방식 코드를 그대로 쓰면 경고 또는 오류가 발생한다. 비유하면 식당 주문을 동기 방식으로 처리하다가 비동기 방식으로 전환한 것과 같다. 예전에는 주문을 받고 그 자리에서 즉시 음식을 내왔지만, 이제는 번호표를 받고 기다렸다가 준비되면 가져가는 방식이다. 이 변경에 맞게 번역 함수 호출 방식도 바뀌어야 했다.
// Next.js 15 이전 (동기)
export default function Page({ params }: { params: { locale: string } }) {
const { t } = useTranslation('common')
return <div>{t('title')}</div>
}
// Next.js 15 이후 (비동기) — 3.0에서 정식 지원
export default async function Page({
params,
}: {
params: Promise<{ locale: string }>
}) {
const { locale } = await params
const { t } = await createTranslation('common')
return <div>{t('title')}</div>
}createTranslation은 App Router 서버 컴포넌트 전용 헬퍼로, 서버에서 직접 번역을 불러올 수 있게 해준다.
Trans 컴포넌트 개선
Trans 컴포넌트가 중첩 배열과 개선된 복수형 처리를 지원하게 됐다. 이전에는 복잡한 번역 키 구조에서 렌더링이 어색하게 되는 경우가 있었다. 비유하면 번역가에게 단어 목록만 주고 문장을 만들어 달라고 했을 때, 문법 규칙이 없으면 어색한 문장이 나오는 것과 같다. 이번 개선으로 HTML 태그, 변수, 복수형 규칙이 하나의 컴포넌트에서 자연스럽게 조합된다.
import Trans from 'next-translate/Trans'
export function Welcome({ name }: { name: string }) {
return (
<Trans
i18nKey="common:welcome"
components={{
strong: <strong />,
br: <br />,
}}
values={{ name }}
/>
)
}주요 변경 사항 비교
| 기능 | 2.x | 3.0 |
|---|---|---|
| Turbopack 지원 | ❌ | ✅ |
| 비동기 params | ❌ | ✅ |
App Router createTranslation | 불안정 | ✅ 안정화 |
| 불필요한 리렌더링 | 발생 가능 | t 함수 최적화로 감소 |
| pages → app 마이그레이션 자동화 | ✅ 있음 | ❌ 제거됨 |
| TypeScript 5.3+ namespace 자동완성 | 없음 | ✅ |
pages → app 마이그레이션 자동화가 제거된 점은 브레이킹 체인지다. 아직 Pages Router를 쓰고 있다면 App Router로 먼저 전환한 뒤에 3.0을 적용해야 한다.
[💡 잠깐! 이 용어는?] 브레이킹 체인지(Breaking Change): 이전 버전 코드가 새 버전에서 동작하지 않게 만드는 변경사항. 라이브러리 메이저 버전 업(1.x → 2.x → 3.x)은 일반적으로 브레이킹 체인지가 허용된다.
마무리
Next-Translate 3.0은 Next.js 생태계의 최신 변화를 따라잡는 업데이트다. Turbopack으로 전환 중인 팀이라면 이번 업데이트가 필수다. createTranslation을 통해 서버 컴포넌트에서 번역이 깔끔하게 처리되는 부분도 실용적이다.
저자는 "상수적인 유지보수 리듬을 유지하겠다"고 약속했다. 앞으로는 1년 공백이 없기를 기대해본다.
참고:
- Next-Translate 3.0 릴리스 노트: https://aralroca.com/blog/next-translate-3-0
- GitHub: https://github.com/aralroca/next-translate
관심 있을 만한 포스트
Vinext — Vite 위에서 Next.js를 1주일 만에 다시 만든 이야기
Cloudflare가 AI와 함께 단 일주일, $1,100의 API 비용으로 Next.js 호환 프레임워크를 Vite 위에 구축한 과정.
Next.js 블로그 만들기 — 정적 블로그에 맞춤 추천 포스트 기능 추가
localStorage에 조회 이력을 저장하고, 태그 가중치 스코어링으로 정적 블로그에서도 개인화 추천을 구현하는 방법.
Next.js 블로그 만들기 — 검색엔진 등록 4종 완전 정복
Google Search Console, Bing Webmaster Tools, 네이버 서치어드바이저, 다음 검색등록까지. Next.js 블로그를 검색엔진에 노출시키는 전체 과정을 정리했다.
Next.js 블로그 만들기 — 정적 블로그에 검색 기능 추가
빌드 타임 검색 인덱스 생성과 클라이언트 사이드 필터링으로 정적 블로그에 검색 기능을 구현하기. Cmd+K 단축키, 오버레이 UI까지.
Next.js 블로그 만들기 — 카드 그리드와 포스트 상세 페이지
Velog 스타일 카드 UI와 MDX 렌더링 상세 페이지 구현. 반응형 그리드, SEO 메타데이터, 정적 사이트 생성까지.
Next.js 15로 개인 블로그 만들기 — 프로젝트 셋업
왜 직접 블로그를 만들었는지, 기술 스택 선정 이유와 프로젝트 초기 구성까지. Next.js 15 + Tailwind CSS v4 + MDX 기반 블로그의 시작.
AI 코딩의 맹점 — Artifacts 없이 에이전트는 기억을 잃는다
PRD, ADR, TDD가 AI 코딩 워크플로우에서 왜 선택이 아닌 필수인지, 실전 구조와 함께 살펴본다.
V8 WasmGC 투기적 최적화 — 가상 메서드를 인라인으로 만드는 법
V8이 WasmGC의 가상 메서드 디스패치에 투기적 인라이닝을 도입해 Dart와 Java 앱에서 최대 8% 성능을 끌어낸 방법.