Next.js(Pages Router) v16에서 로케일 기반 라우팅을 구현하는 방법

로케일 세그먼트로 라우팅 구성하기

문제

다국어 애플리케이션을 구축할 때, 모든 것을 좌우하는 하나의 근본적인 결정이 있습니다: 애플리케이션이 어떤 언어를 표시해야 하는지 어떻게 알 수 있을까요? 명시적인 메커니즘이 없다면, URL /about은 모호해집니다—어떤 언어의 콘텐츠든 나타낼 수 있기 때문입니다. 사용자는 특정 언어 버전의 링크를 공유할 수 없고, 검색 엔진은 어떤 버전이 어떤 대상에게 속하는지 이해하기 어렵습니다. 이러한 모호성은 특정 언어로 된 콘텐츠를 식별하거나 북마크할 수 있는 명확한 방법이 없기 때문에 사용자 경험과 SEO 모두에 문제를 일으킵니다.

해결책

Next.js의 내장 i18n 라우팅 지원을 구성하여 URL 경로에 언어 식별자를 직접 넣으세요. Next.js 구성에서 지원하려는 로케일과 기본 로케일을 선언하세요. Next.js는 자동으로 라우팅을 처리하여 /fr/about/nl-NL/about과 같은 경로를 사용할 수 있게 하며, 기본 로케일은 접두사가 없습니다. 이렇게 하면 모든 경로가 특정 언어에 고유하게 되어 사용자와 검색 엔진 모두에게 모호성이 제거됩니다.

단계

1. next.config.js에 i18n 구성 추가하기

next.config.js 파일에 i18n 구성을 추가하여 애플리케이션이 지원하는 로케일을 선언하세요.

module.exports = {
  i18n: {
    locales: ["en-US", "fr", "nl-NL"],
    defaultLocale: "en-US",
  },
};

로케일은 UTS 로케일 식별자로, 일반적으로 대시로 구분된 언어, 지역 및 스크립트로 구성된 표준화된 형식입니다. defaultLocale은 로케일 접두사가 없는 경로를 방문할 때 사용됩니다.

2. 페이지에서 로케일 정보 접근하기

페이지 컴포넌트에서 로케일 정보에 접근하기 위해 useRouter() 훅을 사용하세요.

import { useRouter } from "next/router";

export default function AboutPage() {
  const router = useRouter();
  const { locale, locales, defaultLocale } = router;

  return (
    <div>
      <h1>About Us</h1>
      <p>Current locale: {locale}</p>
    </div>
  );
}

locale 속성은 현재 활성화된 로케일을 포함하고, locales는 구성된 모든 로케일을 포함하며, defaultLocale은 구성된 기본 로케일을 포함합니다.

3. 데이터 가져오기 함수에서 로케일 접근하기

getStaticProps 또는 getServerSideProps로 페이지를 사전 렌더링할 때, 로케일 정보는 컨텍스트에서 제공됩니다.

import { GetStaticProps } from "next";

export const getStaticProps: GetStaticProps = async (context) => {
  const { locale } = context;

  const messages = await import(`../messages/${locale}.json`);

  return {
    props: {
      messages: messages.default,
    },
  };
};

이를 통해 활성 로케일을 기반으로 빌드 시간 또는 요청 시간에 로케일별 데이터를 로드할 수 있습니다.

4. 로케일 간 연결하기

locale 속성이 있는 next/link를 사용하여 다른 로케일로 전환합니다.

import Link from "next/link";

export default function LanguageSwitcher() {
  return (
    <nav>
      <Link href="/about" locale="en-US">
        English
      </Link>
      <Link href="/about" locale="fr">
        Français
      </Link>
      <Link href="/about" locale="nl-NL">
        Nederlands
      </Link>
    </nav>
  );
}

로케일 속성이 제공되지 않으면 클라이언트 전환 중에 현재 활성화된 로케일이 사용됩니다. 로케일 속성을 사용하면 사용자가 동일한 논리적 페이지에 머물면서 언어를 전환할 수 있습니다.

5. 모든 로케일에 대한 정적 경로 생성하기

getStaticPaths를 활용할 때, 구성된 로케일은 컨텍스트 매개변수의 locales 아래에 제공되고 구성된 defaultLocale은 defaultLocale 아래에 제공됩니다.

import { GetStaticPaths } from "next";

export const getStaticPaths: GetStaticPaths = async (context) => {
  const { locales } = context;

  const paths = locales.flatMap((locale) => [
    { params: { slug: "getting-started" }, locale },
    { params: { slug: "advanced" }, locale },
  ]);

  return {
    paths,
    fallback: false,
  };
};

이렇게 하면 동적 페이지의 모든 로케일 버전이 빌드 시간에 사전 렌더링됩니다.