FE/React

🌐 Next.js App Router에서 next-intl로 다국어(i18n) 설정하기

yhkim_ 2025. 5. 22. 12:20

 

 

Next.js의 App Router 구조에서는 기존의 react-i18next보다 next-intl을 사용하는 것이 훨씬 간단하고 강력하다.
이 글에서는 Next.js 13~15 (App Router 기반) 프로젝트에 next-intl을 적용하는 전체 과정을 정리한다.

 

 

📦 1. 설치

npm install next-intl

 

 

📁 2. 폴더 구조 설정

.
├── app/
│   ├── [locale]/
│   │   ├── page.tsx
│   │   └── layout.tsx
│   └── layout.tsx
├── messages/
│   ├── ko.json
│   └── en.json

 

 

3. 메시지 파일 생성

messages/ko.json

{
  "home.title": "홈페이지에 오신 걸 환영합니다"
}

 

messages/en.json

{
  "home.title": "Welcome to the homepage"
}

 

 

4. middleware.ts로 locale redirect 설정

// middleware.ts
import { NextRequest, NextResponse } from "next/server";
import { match as matchLocale } from "@formatjs/intl-localematcher";

const locales = ["en", "ko"];
const defaultLocale = "ko";

function getLocale(request: NextRequest): string {
  const acceptLanguage = request.headers.get("accept-language");
  if (!acceptLanguage) return defaultLocale;

  const matched = matchLocale(acceptLanguage.split(","), locales, defaultLocale);
  return matched;
}

export function middleware(request: NextRequest) {
  const { pathname } = request.nextUrl;

  if (
    pathname.startsWith("/_next") ||
    pathname.includes(".") ||
    locales.some((locale) => pathname.startsWith(`/${locale}`))
  ) {
    return;
  }

  const locale = getLocale(request);
  const url = request.nextUrl.clone();
  url.pathname = `/${locale}${pathname}`;
  return NextResponse.redirect(url);
}

export const config = {
  matcher: ["/((?!api|_next/static|_next/image|favicon.ico).*)"],
};

 

 

5. app/layout.tsx에서 locale layout 연결

// app/layout.tsx
import { notFound } from "next/navigation";
import { unstable_setRequestLocale } from "next-intl/server";

export function generateStaticParams() {
  return [{ locale: "ko" }, { locale: "en" }];
}

export default function RootLayout({
  children,
  params,
}: {
  children: React.ReactNode;
  params: { locale: string };
}) {
  const locale = params.locale;
  unstable_setRequestLocale(locale);

  if (!["ko", "en"].includes(locale)) notFound();

  return (
    <html lang={locale}>
      <body>{children}</body>
    </html>
  );
}

 

 

🧩 6. 각 페이지에서 다국어 메시지 사용

// app/[locale]/page.tsx
import { useTranslations } from "next-intl";

export default function HomePage() {
  const t = useTranslations("home");

  return <h1>{t("title")}</h1>;
}

 

✅ 결과

  • /ko로 접근하면 한국어 메시지 출력
  • /en으로 접근하면 영어 메시지 출력
  • 브라우저 언어에 따라 자동 리디렉션

 

💡 추가 팁

  • 라우팅 경로도 다국어 지원하려면 next-intl/navigation 사용 가능
  • Next.js의 generateStaticParams, generateMetadata에 locale 처리 포함 가능
  • 번역 JSON 파일은 키 구조를 점(.)으로 구분하면 그룹화 가능 (예: home.title, home.button.submit)

 

마무리

Next.js App Router 환경에서는 next-intl이 공식에 가까울 정도로 강력하고 깔끔한 다국어 처리 도구이다.
복잡한 설정 없이도 SSR, SSG 환경에서 완벽하게 다국어 UI를 제공할 수 있다.

🌏 글로벌 서비스를 준비 중이라면 next-intl 도입을 꼭 고려해보자!