Language/Next.js

[Next.js] i18n 로컬화(지역화) 및 국제화 방법(13 버전 이상, App Router)

  • -
반응형

끊임없이 진화하는 웹 개발 환경에서 Next.js는 강력하고 성능이 뛰어난 애플리케이션을 구축하기 위한 프레임워크로 등장했습니다. 버전 13이 출시되면서 Next.js는 특히 국제화(I18n) 및 현지화에 맞춰 앱 라우터에 상당한 개선 사항을 도입했습니다. 효율적인 라우팅은 모든 웹 애플리케이션의 백본이며 Next.js 13은 전역화된 콘텐츠 탐색을 원활하게 통합하여 이를 한 단계 더 발전시킵니다.

[Next.js] i18n 로컬화(지역화) 및 국제화 방법(13 버전 이상, App Router)
[Next.js] i18n 로컬화(지역화) 및 국제화 방법(13 버전 이상, App Router)

국제화(I18n, Internationalization) 및 지역화( 번역, localization) 이해

종종 I18n으로 축약되는 국제화는 엔지니어링 변경 없이 다양한 언어와 지역적 차이에 적응할 수 있는 소프트웨어 애플리케이션을 설계하고 개발하는 프로세스입니다. 반면에 현지화에는 애플리케이션을 특정 지역이나 시장에 맞게 번역하고 적용하는 작업이 포함됩니다. 글로벌한 접근이 가장 중요한 세상에서는 강력한 I18n 전략이 개발자에게 매우 중요합니다.

 

  • 사용자의 언어 선호도에 따라 페이지를 렌더링합니다.
  • 페이지의 텍스트 및 이미지와 같은 리소스를 해당 언어로 번역합니다.
  • 날짜, 시간, 통화와 같은 로케일별로 구분되는 데이터를 처리합니다.

국제화를 위한 Next.js 앱 라우터(13 버전)의 주요 기능

Next.js 13은 국제화를 개발 프로세스의 필수적인 부분으로 만드는 일련의 기능을 제공합니다. 단순화된 구성부터 다국어 콘텐츠를 위한 동적 라우팅에 이르기까지 개발자는 이러한 기능을 활용하여 다양한 청중에게 원활하게 서비스를 제공하는 애플리케이션을 만들 수 있습니다.

국제화를 위한 Next.js 앱 라우터 설정 방법

국제화를 위해 Next.js를 구성하는 것은 처음에는 어려워 보일 수 있지만 올바른 지침을 따르면 프로세스가 간단해집니다. I18n용 Next.js를 설정하는 데 필요한 필수 단계와 구성을 살펴보겠습니다. 일전 버전에서는 `next-translate` 플러그인 라이브러리 등을 사용하여 번역 작업을 진행하였다면 13 version 이상에서는 Next.js에서 아예 자체적으로 현지화 및 번역 작업을 제공하고 있다(개인적으로는 조금 복잡해진거 같다는 느낌은 있지만)

i18n.config.js 파일을 생성한다

// (root)/i18n.config.js(ts)
export const i18n = {
  defaultLocale: "en",
  locales: ["en", "ko"],
} as const;

export type Locale = (typeof i18n)["locales"][number];

Middleware.js file 파일도 생성한다

“@formatjs/intl-localematcher”, “negotiator”, (“@types/negotiator”) 라이브러리를 미리 설치해야한다

// (root)/middleware.js(ts)

import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";

import { i18n } from "@/i18n.config";

import { match as matchLocale } from "@formatjs/intl-localematcher";
import Negotiator from "negotiator";

function getLocale(request: NextRequest): string | undefined {
  const negotiatorHeaders: Record<string, string> = {};
  request.headers.forEach((value, key) => (negotiatorHeaders[key] = value));

  // @ts-ignore locales are readonly
  const locales: string[] = i18n.locales;
  const languages = new Negotiator({ headers: negotiatorHeaders }).languages();

  const locale = matchLocale(languages, locales, i18n.defaultLocale);
  return locale;
}

export function middleware(request: NextRequest) {
  const pathname = request.nextUrl.pathname;
  const pathnameIsMissingLocale = i18n.locales.every(
    (locale) => !pathname.startsWith(`/${locale}/`) && pathname !== `/${locale}`
  );

  // Redirect if there is no locale
  if (pathnameIsMissingLocale) {
    const locale = getLocale(request);
    return NextResponse.redirect(
      new URL(
        `/${locale}${pathname.startsWith("/") ? "" : "/"}${pathname}`,
        request.url
      )
    );
  }
}

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

[lang] 폴더를 만들고 모든 앱 페이지를 [lang] 폴더에 넣어야 합니다.

번역할 텍스트를 json 형식으로 만듭니다

// src/translate/en.json - you can create folder any other location

{
  "products": {
    "cart": "Add to Cart"
  }
}

// trnalate/ko.json

{
  "products": {
    "cart": "카트"
  }
}

번역을 위한 함수 파일을 만듭니다.

// src/lib/translation.ts

import "server-only";
import type { Locale } from "@/i18n.config";

const translation = {
  en: () => import("@/src/translate/en.json").then((module) => module.default),
  ko: () => import("@/src/translate/ko.json").then((module) => module.default),
};

export const getTranslation = async (locale: Locale) => {
  return locale == "ko" ? translation.ko() : translation.en();
};

텍스트를 번역해줍니다

// app/[lang]/page.tsx

import { getTranslation } from "@/src/lib/translation";

export default async function Page({ params: { lang } }) {
  const dict = await getTranslation(lang) // en
  return <button>{dict.products.cart}</button> // Add to Cart
}

Static Generation

특정 로케일 세트에 대한 정적 경로를 생성하려면 페이지나 레이아웃에 generateStaticParams를 사용할 수 있습니다. 예를 들어 루트 레이아웃에서는 전역적일 수 있습니다.

// app/[lang]/layout.js

export async function generateStaticParams() {
  return [{ lang: 'en' }, { lang: 'ko' }]
}

export default function Root({ children, params }) {
  return (
    <html lang={params.lang}>
      <body>{children}</body>
    </html>
  )
}

Next.js 13 라우터로 다국어 콘텐츠 탐색

Next.js 13의 뛰어난 기능 중 하나는 다양한 언어에 대한 동적 라우팅 기능입니다. 향상된 앱 라우터를 통해 개발자는 선호하는 언어로 콘텐츠를 통해 사용자를 쉽게 탐색할 수 있어 전반적인 사용자 경험이 향상됩니다.

결과

결론적으로 Next.js App Router(13 버전) 국제화는 글로벌 규모의 애플리케이션을 만들려는 개발자에게 새로운 문을 열어줍니다. 동적 라우팅, 로캘별 구성 요소 및 SEO 최적화의 발전으로 Next.js 13은 다국어 웹 애플리케이션 제작을 위한 강력한 도구가 되었습니다. 웹 개발의 미래를 수용하면서 국제화를 통합하는 것은 단순한 추세가 아니라 필수입니다.

 

공식 문서

https://nextjs.org/docs/app/building-your-application/routing/internationalization

반응형
Contents

포스팅 주소를 복사했습니다

이 글이 도움이 되었다면 공감 부탁드립니다.