사용자의 선호 언어 감지하기
새로운 방문자를 가장 적합한 언어로 리다이렉트
문제
사용자가 애플리케이션의 루트(예: /)에 처음 방문할 때, 영어와 같은 기본 언어가 표시됩니다. 이는 다른 언어를 사용하는 사용자들에게 즉각적인 불편함을 초래하며, 브라우저가 이미 그들의 선호도를 전달하고 있음에도 불구하고 수동으로 언어 전환기를 찾도록 강요합니다.
해결책
루트 경로(/)에 대한 요청을 가로채는 미들웨어를 사용합니다. 사용자의 Accept-Language HTTP 헤더를 확인하여 선호하는 언어를 찾습니다. 해당 언어가 애플리케이션에서 지원된다면, 사용자를 해당 언어의 루트(예: /fr)로 리디렉션합니다. 지원되지 않는다면, 기본 언어(예: /en)로 리디렉션합니다.
단계
1. 언어 파서 설치
Accept-Language 헤더는 복잡할 수 있습니다(예: fr-CH, fr;q=0.9, en;q=0.8). 작은 라이브러리가 이 헤더를 파싱하고 지원하는 언어 목록에서 최적의 일치를 찾는 데 도움이 됩니다.
터미널에서 다음 명령을 실행하세요:
npm install accept-language-parser
2. 언어 및 기본값 정의
지원하는 언어 목록을 저장하고 기본값을 정의하는 중앙 구성 파일을 생성합니다. 이 기본값은 사용자의 브라우저 환경설정이 지원하는 언어와 일치하지 않을 때 사용됩니다.
// i18n.config.ts
export const locales = ['en', 'es', 'fr'];
export const defaultLocale = 'en';
3. 미들웨어 생성
프로젝트 루트에 middleware.ts 파일을 생성합니다. 이 파일은 들어오는 요청에서 실행되어 경로와 헤더를 확인할 수 있게 합니다.
// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
import parser from 'accept-language-parser';
import { locales, defaultLocale } from './i18n.config';
// 최적의 언어 일치를 찾는 헬퍼 함수
function getBestLocale(acceptLangHeader: string | null) {
if (!acceptLangHeader) {
return defaultLocale;
}
// 파서를 사용하여 최적의 지원 언어 찾기
const bestMatch = parser.pick(locales, acceptLangHeader, {
loose: true,
});
return bestMatch || defaultLocale;
}
export function middleware(request: NextRequest) {
const { pathname } = request.nextUrl;
// 1. 요청이 루트 경로인지 확인
if (pathname === '/') {
// 사용자의 선호 언어 가져오기
const acceptLang = request.headers.get('Accept-Language');
const bestLocale = getBestLocale(acceptLang);
// 최적으로 일치하는 언어 경로로 리디렉션
request.nextUrl.pathname = `/${bestLocale}`;
return NextResponse.redirect(request.nextUrl);
}
// 2. 다른 모든 경로에 대해서는 정상적으로 계속 진행
return NextResponse.next();
}
export const config = {
matcher: [
// 다음으로 시작하는 모든 경로 건너뛰기:
// - api (API 라우트)
// - _next/static (정적 파일)
// - _next/image (이미지 최적화 파일)
// - favicon.ico (파비콘 파일)
'/((?!api|_next/static|_next/image|favicon.ico).*)',
],
};
이 코드는 루트 경로(/)에 대해서만 로직을 실행합니다. 사용자가 /를 방문하면 Accept-Language 헤더를 확인하고 최적의 일치(예: es)를 찾아 /es로 리디렉션합니다. /en/about과 같은 다른 모든 요청은 이 로직에 의해 무시되고 그대로 통과합니다.