Cómo crear un componente de selector de idioma en TanStack Start v1
Cambia de idioma mientras permaneces en la misma página
Problema
Cuando los usuarios cambian de idioma en una aplicación multilingüe, esperan permanecer en la misma página viendo el mismo contenido en el nuevo idioma. Un selector de idioma mal implementado trata la selección de idioma como una navegación a un destino diferente, a menudo redirigiendo a los usuarios a la página de inicio y perdiendo completamente su ubicación. Esto interrumpe el flujo del usuario y crea frustración, especialmente cuando los usuarios están inmersos en un flujo de trabajo o visualizando contenido específico. El desafío es crear un selector que cambie únicamente el segmento de idioma de la URL mientras preserva el resto de la ruta, los parámetros de búsqueda y el hash.
Solución
Crea un componente de selector de idioma que lea la ruta actual de la URL y construya enlaces para cada idioma disponible reemplazando el segmento de locale en la ruta. Extrae el locale actual de la estructura de la URL, luego genera nuevas rutas para otros idiomas soportados sustituyendo la porción de locale mientras mantienes intactos todos los demás segmentos de la URL. Utiliza estas rutas para renderizar enlaces que permitan a los usuarios cambiar de idioma sin perder el contexto de su página actual.
Pasos
1. Define los locales soportados
Crea un archivo de configuración que liste todos los idiomas que tu aplicación soporta e identifique el locale predeterminado.
export const locales = ["en", "fr", "es", "de"] as const;
export type Locale = (typeof locales)[number];
export const defaultLocale: Locale = "en";
Esta configuración sirve como la única fuente de verdad para los idiomas disponibles y se utilizará para generar los enlaces del selector.
2. Crea una función auxiliar para extraer el locale actual del pathname
Escribe una función de utilidad que analice el pathname y extraiga el segmento de locale si está presente.
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;
}
Esta función inspecciona el primer segmento de la ruta y lo devuelve si coincide con una configuración regional admitida; de lo contrario, recurre a la predeterminada.
3. Crear una función auxiliar para construir rutas localizadas
Escribe una función que tome la ruta actual y una configuración regional de destino, y luego construya una nueva ruta con el segmento de configuración regional reemplazado.
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("/");
}
Esta función reemplaza un segmento de configuración regional existente o antepone la configuración regional de destino a la ruta, asegurando que la nueva URL apunte a la misma página en un idioma diferente.
4. Construir el componente de selector de idioma
Crea un componente que utilice la ubicación actual para generar enlaces para todos los idiomas admitidos.
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>
);
}
El componente lee la ruta actual, determina la configuración regional activa y renderiza un enlace para cada idioma admitido que preserve la estructura de la página actual, los parámetros de búsqueda y el fragmento hash. Los usuarios pueden cambiar de idioma mientras permanecen en la misma página lógica.