Как проверить параметры локали в URL-адресах в TanStack Start v1

Корректная обработка неподдерживаемых кодов локали

Проблема

Когда языковые коды становятся частью структуры URL, они превращаются в пользовательский ввод, который необходимо проверять. Пользователи могут вручную ввести любую строку в сегмент локали — /xx/about, /gibberish/contact или /typo123/products — так же легко, как и допустимые коды, такие как /en/about или /fr/contact. Без проверки приложение может попытаться загрузить переводы для несуществующих локалей, отобразить некорректный контент или завершиться сбоем. Каждая недопустимая локаль представляет собой потенциальный тупик, из которого пользователи не могут восстановиться или перейти на рабочие страницы.

Непроверенные параметры локали создают непредсказуемое поведение. Приложение может тихо не загрузить переводы, отобразить смесь резервного и отсутствующего контента или вызвать ошибки выполнения при доступе к ключам перевода. Пользователи, которые следуют по сломанным ссылкам или ошибаются в URL, остаются без четкой обратной связи о том, что пошло не так и как это исправить.

Решение

Проверяйте параметр локали из URL на соответствие списку поддерживаемых локалей в функции beforeLoad маршрута. Если локаль недопустима или отсутствует, перенаправьте пользователя на допустимый URL с локалью по умолчанию или вызовите ошибку "не найдено", чтобы отобразить полезную страницу ошибки. Это гарантирует, что обрабатываются только поддерживаемые локали, и пользователи всегда попадают на допустимую, переводимую страницу.

Функция beforeLoad выполняется до загрузки маршрута, что делает её идеальным местом для проверки локали. Вызывая redirect() или ошибку notFound(), вы предотвращаете рендеринг маршрута с недопустимой локалью и направляете пользователей в рабочее состояние.

Шаги

1. Определите поддерживаемые локали

Создайте массив констант с допустимыми кодами локалей и функцию проверки с учётом типов.

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

type Locale = (typeof SUPPORTED_LOCALES)[number];

function isValidLocale(locale: string | undefined): locale is Locale {
  return SUPPORTED_LOCALES.includes(locale as Locale);
}

Это обеспечивает единый источник правды для поддерживаемых локалей и повторно используемую функцию проверки, которую понимает TypeScript.

2. Создайте маршрут с проверкой локали

Используйте необязательный параметр локали и проверьте его в beforeLoad.

import { createFileRoute, redirect } from "@tanstack/react-router";

const DEFAULT_LOCALE: Locale = "en";

export const Route = createFileRoute("/{-$locale}")({
  beforeLoad: ({ params }) => {
    const { locale } = params;

    if (locale && !isValidLocale(locale)) {
      throw redirect({
        to: "/{-$locale}",
        params: { locale: undefined },
        replace: true,
      });
    }

    return {
      locale: (locale as Locale) || DEFAULT_LOCALE,
    };
  },
});

Функция beforeLoad проверяет параметр локали. Если он существует, но недействителен, пользователь перенаправляется на тот же путь без префикса локали, что приводит к использованию локали по умолчанию. Проверенная локаль возвращается в контексте для использования дочерними маршрутами.

3. Проверьте локаль в вложенных маршрутах

Для маршрутов, которые требуют локаль, проверьте её и вызовите notFound(), если она недействительна.

import { createFileRoute, notFound } from "@tanstack/react-router";

export const Route = createFileRoute("/{-$locale}/products")({
  beforeLoad: ({ params }) => {
    const { locale } = params;

    if (locale && !isValidLocale(locale)) {
      throw notFound();
    }

    return {
      locale: (locale as Locale) || DEFAULT_LOCALE,
    };
  },
  component: ProductsPage,
});

function ProductsPage() {
  const { locale } = Route.useRouteContext();
  return <div>Продукты на {locale}</div>;
}

Этот подход показывает страницу "не найдено" для недействительных локалей вместо перенаправления, что полезно, если вы хотите указать, что URL-адрес некорректен, а не исправлять его молча.

4. Добавьте компонент "не найдено" для недействительных локалей

Определите notFoundComponent в корневом маршруте, чтобы аккуратно обрабатывать ошибки недействительных локалей.

import { createRootRoute } from "@tanstack/react-router";

export const Route = createRootRoute({
  notFoundComponent: () => {
    return (
      <div>
        <h1>Страница не найдена</h1>
        <p>Запрошенный язык или страница не существует.</p>
        <a href="/">Перейти на главную страницу</a>
      </div>
    );
  },
});

Этот компонент отображается, когда notFound() вызывается из beforeLoad, предоставляя пользователям понятное сообщение и способ вернуться на действительную страницу.