TanStack Start v1에서 언어 전환 컴포넌트를 구축하는 방법
같은 페이지에 머물면서 언어 전환하기
문제
다국어 애플리케이션에서 사용자가 언어를 전환할 때, 그들은 동일한 페이지에 머물면서 새로운 언어로 동일한 콘텐츠를 보기를 기대합니다. 제대로 구현되지 않은 언어 전환기는 언어 선택을 다른 목적지로의 이동으로 취급하여, 종종 사용자를 홈페이지로 리디렉션하고 현재 위치를 완전히 잃게 만듭니다. 이는 사용자 흐름을 방해하고 좌절감을 주는데, 특히 사용자가 워크플로우 깊숙이 들어가 있거나 특정 콘텐츠를 보고 있을 때 더욱 그렇습니다. 이 문제의 핵심은 URL의 언어 세그먼트만 변경하고 나머지 경로, 검색 매개변수 및 해시를 유지하는 전환기를 구축하는 것입니다.
해결책
현재 URL 경로명을 읽고 경로의 로케일 세그먼트를 대체하여 각 사용 가능한 언어에 대한 링크를 구성하는 언어 전환기 컴포넌트를 구축합니다. URL 구조에서 현재 로케일을 추출한 다음, 다른 URL 세그먼트는 그대로 유지하면서 로케일 부분만 대체하여 지원되는 다른 언어에 대한 새 경로를 생성합니다. 이러한 경로를 사용하여 사용자가 현재 페이지 컨텍스트를 잃지 않고 언어를 전환할 수 있는 링크를 렌더링합니다.
단계
1. 지원되는 로케일 정의
애플리케이션이 지원하는 모든 언어를 나열하고 기본 로케일을 식별하는 구성 파일을 만듭니다.
export const locales = ["en", "fr", "es", "de"] as const;
export type Locale = (typeof locales)[number];
export const defaultLocale: Locale = "en";
이 구성은 사용 가능한 언어에 대한 단일 진실 소스 역할을 하며 전환기 링크를 생성하는 데 사용됩니다.
2. 경로명에서 현재 로케일을 추출하는 헬퍼 만들기
경로명을 파싱하고 존재하는 경우 로케일 세그먼트를 추출하는 유틸리티 함수를 작성합니다.
import { defaultLocale, locales, type Locale } from "./locales";
export function getLocaleFromPathname(pathname: string): Locale {
const segments = pathname.split("/").filter(Boolean);
const firstSegment = segments[0];
if (firstSegment && locales.includes(firstSegment as Locale)) {
return firstSegment as Locale;
}
return defaultLocale;
}
이 함수는 첫 번째 경로 세그먼트를 검사하고 지원되는 로케일과 일치하면 해당 세그먼트를 반환하며, 그렇지 않으면 기본 로케일로 폴백합니다.
3. 지역화된 경로를 구축하는 헬퍼 생성
현재 경로명과 대상 로케일을 받아 로케일 세그먼트가 교체된 새 경로를 구성하는 함수를 작성합니다.
import { defaultLocale, locales, type Locale } from "./locales";
export function getLocalizedPath(
pathname: string,
targetLocale: Locale,
): string {
const segments = pathname.split("/").filter(Boolean);
const firstSegment = segments[0];
const hasLocalePrefix =
firstSegment && locales.includes(firstSegment as Locale);
if (hasLocalePrefix) {
segments[0] = targetLocale;
} else {
segments.unshift(targetLocale);
}
return "/" + segments.join("/");
}
이 함수는 기존 로케일 세그먼트를 교체하거나 경로 앞에 대상 로케일을 추가하여 새 URL이 다른 언어로 동일한 페이지를 가리키도록 합니다.
4. 언어 전환기 컴포넌트 구축
현재 위치를 사용하여 지원되는 모든 언어에 대한 링크를 생성하는 컴포넌트를 만듭니다.
import { Link } from "@tanstack/react-router";
import { useLocation } from "@tanstack/react-router";
import { locales, type Locale } from "./locales";
import { getLocaleFromPathname, getLocalizedPath } from "./locale-helpers";
export function LanguageSwitcher() {
const location = useLocation();
const currentLocale = getLocaleFromPathname(location.pathname);
return (
<nav>
<ul>
{locales.map((locale) => {
const isActive = locale === currentLocale;
const localizedPath = getLocalizedPath(location.pathname, locale);
return (
<li key={locale}>
<Link
to={localizedPath}
search={location.search}
hash={location.hash}
aria-current={isActive ? "page" : undefined}
>
{locale.toUpperCase()}
</Link>
</li>
);
})}
</ul>
</nav>
);
}
이 컴포넌트는 현재 경로명을 읽고, 활성 로케일을 결정한 다음, 현재 페이지 구조, 검색 매개변수 및 해시 프래그먼트를 유지하는 각 지원 언어에 대한 링크를 렌더링합니다. 사용자는 동일한 논리적 페이지에 머물면서 언어를 전환할 수 있습니다.