TanStack Start v1에서 내비게이션 링크의 로케일을 유지하는 방법

내부 내비게이션에서 로케일 유지

문제

로케일 정보가 URL 경로에 인코딩되어 있는 경우, 모든 탐색 링크는 일관된 사용자 경험을 유지하기 위해 해당 로케일을 보존해야 합니다. 사용자가 /fr/products에서 사이트의 프랑스어 버전을 탐색하는 경우, /about로의 링크를 클릭하면 기본 언어로 전환되어 세션 컨텍스트가 중단됩니다. 모든 링크에 로케일 매개변수를 하드코딩하는 것은 반복적이고 오류가 발생하기 쉬우며, 특히 애플리케이션이 성장하고 컴포넌트 전체에 더 많은 링크가 추가될수록 더욱 그렇습니다.

로케일 인식 탐색에 대한 체계적인 접근 방식이 없으면, 개발자는 모든 Link 컴포넌트를 통해 로케일을 수동으로 전달하거나 사용자가 세션 중간에 예기치 않게 기본 언어로 전환되는 것을 받아들여야 하는 선택에 직면하게 됩니다. 두 결과 모두 사용자 경험을 저하시키고 유지 관리 부담을 증가시킵니다.

솔루션

프레임워크의 Link 주위에 래퍼 컴포넌트를 생성하여 URL에서 현재 로케일을 자동으로 읽고 모든 탐색 대상의 params prop에 주입합니다. 이 로직을 재사용 가능한 단일 컴포넌트에 중앙 집중화함으로써, 모든 내부 링크는 개발자가 모든 호출 지점에서 로케일 매개변수를 수동으로 전달할 필요 없이 로케일 인식 동작을 상속받습니다.

이 접근 방식은 라우터의 훅을 사용하여 라우트 매개변수에서 활성 로케일을 읽은 다음, 해당 로케일을 대상 링크의 매개변수에 병합하는 방식으로 작동합니다. 래퍼는 탐색 전반에 걸쳐 로케일 연속성을 보장하면서 다른 모든 Link 기능을 보존합니다.

단계

현재 로케일을 읽고 내비게이션 매개변수에 자동으로 포함하는 컴포넌트를 구축합니다.

import { Link, LinkProps, useParams } from "@tanstack/react-router";

type LocaleLinkProps = LinkProps & {
  to: string;
};

export function LocaleLink(props: LocaleLinkProps) {
  const params = useParams({ strict: false });
  const currentLocale = params.locale;

  const enhancedParams = {
    ...props.params,
    ...(currentLocale && { locale: currentLocale }),
  };

  return <Link {...props} params={enhancedParams} />;
}

이 컴포넌트는 strict: false와 함께 useParams를 사용하여 애플리케이션의 모든 라우트에서 매개변수에 액세스하고, 현재 locale를 추출하여 기본 Link에 전달된 params prop에 병합합니다. 스프레드 연산자는 명시적으로 제공된 모든 params가 우선순위를 갖도록 보장합니다.

애플리케이션 전체에서 표준 Link 컴포넌트를 LocaleLink로 교체하세요.

import { createFileRoute } from "@tanstack/react-router";
import { LocaleLink } from "../components/LocaleLink";

export const Route = createFileRoute("/{-$locale}/products")({
  component: ProductsPage,
});

function ProductsPage() {
  return (
    <div>
      <h1>Products</h1>
      <nav>
        <LocaleLink to="/{-$locale}/about">About</LocaleLink>
        <LocaleLink to="/{-$locale}/contact">Contact</LocaleLink>
        <LocaleLink to="/{-$locale}/products/$id" params={{ id: "123" }}>
          Product 123
        </LocaleLink>
      </nav>
    </div>
  );
}

사용자가 /fr/products를 방문하면 모든 LocaleLink 컴포넌트가 자동으로 /fr/about, /fr/contact, /fr/products/123로 해석됩니다. 로케일 매개변수는 각 링크 위치에서 수동 개입 없이 유지됩니다.

3. 필요 시 locale 전환을 명시적으로 처리

언어 전환 컴포넌트의 경우 표준 Link를 직접 사용하여 자동 로케일 주입을 우회하세요.

import { Link, useParams } from "@tanstack/react-router";

export function LanguageSwitcher() {
  const params = useParams({ strict: false });
  const currentPath = window.location.pathname.replace(/^\/(en|fr|es)/, "");

  return (
    <div>
      <Link to={`/{-$locale}${currentPath}`} params={{ locale: "en" }}>
        English
      </Link>
      <Link to={`/{-$locale}${currentPath}`} params={{ locale: "fr" }}>
        Français
      </Link>
      <Link to={`/{-$locale}${currentPath}`} params={{ locale: "es" }}>
        Español
      </Link>
    </div>
  );
}

언어 전환기는 로케일 매개변수에 대한 명시적 제어가 필요하므로 표준 Link 컴포넌트를 사용하고 locale 매개변수를 명시적으로 설정합니다. 이를 통해 사용자는 동일한 논리적 페이지에 머무르면서 언어를 변경할 수 있습니다.