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;
}
}
이를 통해 브라우저 언어 정보를 사용할 수 없는 경우에도 애플리케이션이 항상 유효한 로케일 경로로 리디렉션되도록 보장합니다.