Next.js(Pages Router) v16에서 사용자 언어 환경설정 감지하는 방법

브라우저 환경설정에 따른 자동 리디렉션

문제

모든 브라우저는 각 HTTP 요청과 함께 Accept-Language 헤더를 전송하며, 이는 사용자가 선호하는 언어를 우선순위에 따라 나타냅니다. 대부분의 애플리케이션은 이 중요한 신호를 무시하고 모든 방문자에게 기본 언어를 제공하여, 애플리케이션이 이미 사용자의 선호도를 알고 있음에도 불구하고 사용자가 수동으로 언어 전환기를 찾도록 강요합니다. 이는 첫 방문 시 불필요한 마찰을 만들고 사용자가 자신의 언어로 된 콘텐츠를 찾기 전에 사이트를 이탈하게 만들 수 있습니다.

사용자가 애플리케이션의 루트 경로에 도달했을 때, 그들의 언어 선호도를 확인하고 즉시 이해할 수 있는 언어로 된 콘텐츠로 안내할 기회가 있습니다. 이러한 감지 없이는 국제 사용자들은 브라우저 설정에 관계없이 영어 우선 경험에 직면하게 되어, 환영하는 현지화된 첫인상을 제공할 기회를 놓치게 됩니다.

해결책

루트 경로에 대한 모든 요청에서 서버 측 로직을 실행하는 루트 페이지를 만듭니다. 들어오는 요청에서 Accept-Language HTTP 헤더를 읽고 이를 분석하여 사용자가 가장 선호하는 언어를 추출합니다. 이 언어를 애플리케이션이 지원하는 언어 목록과 비교합니다. 일치하는 항목이 발견되면 사용자를 해당 언어의 루트 경로로 리디렉션합니다. 지원되는 언어와 일치하는 것이 없으면 기본 언어 경로로 리디렉션합니다.

이 접근 방식은 Next.js의 getServerSideProps 함수를 활용하며, 이 함수는 각 요청에 대해 서버에서 실행되고 리디렉션 응답을 반환할 수 있습니다. 루트 경로에서 감지를 처리함으로써 애플리케이션은 지능적인 기본값을 제공하면서도 사용자가 필요한 경우 나중에 수동으로 언어를 전환할 수 있도록 합니다.

단계

1. Accept-Language 헤더를 분석하는 라이브러리 설치

Accept-Language 헤더에는 선택적 품질 값이 있는 쉼표로 구분된 언어 코드 목록이 포함되어 있으며 이를 파싱해야 합니다. 이 형식을 처리하기 위한 파서 라이브러리를 설치하세요.

npm install accept-language-parser

이 라이브러리는 헤더 문자열에서 언어 코드와 품질 점수를 추출하여 우선순위 순서대로 반환합니다.

2. 서버 측 리디렉션 로직이 있는 루트 페이지 생성

루트 디렉토리로 자동 라우팅될 pages/index.tsx 파일을 생성합니다. 목적지와 영구 플래그가 있는 리디렉션 객체를 반환하기 위해 getServerSideProps를 사용하세요.

import { GetServerSideProps } from "next";
import parser from "accept-language-parser";

const SUPPORTED_LOCALES = ["en", "fr", "es", "de"];
const DEFAULT_LOCALE = "en";

export default function RootPage() {
  return null;
}

export const getServerSideProps: GetServerSideProps = async (context) => {
  const acceptLanguageHeader = context.req.headers["accept-language"];

  let targetLocale = DEFAULT_LOCALE;

  if (acceptLanguageHeader) {
    const languages = parser.parse(acceptLanguageHeader);

    const matchedLanguage = languages.find((lang) =>
      SUPPORTED_LOCALES.includes(lang.code),
    );

    if (matchedLanguage) {
      targetLocale = matchedLanguage.code;
    }
  }

  return {
    redirect: {
      destination: `/${targetLocale}`,
      permanent: false,
    },
  };
};

getServerSideProps 함수는 각 요청마다 실행되어 Accept-Language 헤더를 읽고 페이지 콘텐츠가 렌더링되기 전에 적절한 로케일 경로로 리디렉션합니다.

3. 지원되는 로케일 정의

애플리케이션이 지원하는 언어와 일치하도록 SUPPORTED_LOCALES 배열을 업데이트하세요. 파서는 품질 순서대로 언어를 반환하고, 코드는 첫 번째 일치 항목을 선택합니다.

const SUPPORTED_LOCALES = ["en", "fr", "es", "de", "ja", "zh"];
const DEFAULT_LOCALE = "en";

파서는 품질이 높은 것부터 낮은 것 순으로 언어를 정렬하여 반환하므로, 발견된 첫 번째 지원 언어는 애플리케이션이 충족할 수 있는 사용자의 가장 강한 선호도를 나타냅니다.

4. Accept-Language 헤더가 없는 경우 처리하기

일부 요청에는 Accept-Language 헤더가 포함되지 않을 수 있습니다. 코드는 헤더의 존재 여부를 확인하고 헤더가 없을 경우 기본 로케일로 대체합니다.

if (acceptLanguageHeader) {
  const languages = parser.parse(acceptLanguageHeader);

  const matchedLanguage = languages.find((lang) =>
    SUPPORTED_LOCALES.includes(lang.code),
  );

  if (matchedLanguage) {
    targetLocale = matchedLanguage.code;
  }
}

이렇게 하면 브라우저 언어 정보를 사용할 수 없는 경우에도 애플리케이션이 항상 유효한 로케일 경로로 리디렉션됩니다.