Construyendo un selector de idiomas
Permitiendo a los usuarios cambiar de idioma en cualquier página
Problema
Un usuario está en una página específica, como /en/products/123, y quiere ver la misma página en otro idioma. Al hacer clic en un selector de idioma (por ejemplo, 'Français') a menudo lo envía de vuelta a la página de inicio (/fr/) en lugar de a la página de producto correspondiente, interrumpiendo su flujo de trabajo y obligándolo a navegar nuevamente.
Solución
Crear un componente de cliente que lea la ruta actual de la URL. Genera una lista de enlaces para todos los otros idiomas compatibles reemplazando el segmento de idioma actual en la ruta. También establece una cookie de preferencia al hacer clic, asegurando que la elección se recuerde para futuras visitas.
Pasos
1. Define tu configuración de idioma
Asegúrate de que tu archivo i18n.config.ts incluya la lista de locales y el nombre de la cookie que utilizarás.
// i18n.config.ts
export const locales = ['en', 'es', 'fr'];
export const defaultLocale = 'en';
export const localeCookieName = 'NEXT_LOCALE';
2. Crea el componente selector de idioma
Crea un nuevo archivo, por ejemplo, app/components/LanguageSwitcher.tsx. Este debe ser un componente de cliente para usar hooks como usePathname.
// app/components/LanguageSwitcher.tsx
'use client';
import { usePathname } from 'next/navigation';
import Link from 'next/link';
import { locales, localeCookieName } from '@/i18n.config';
export default function LanguageSwitcher() {
const pathname = usePathname();
// Esta función establece la cookie
const setLocaleCookie = (locale: string) => {
document.cookie = `${localeCookieName}=${locale}; path=/; max-age=31536000; samesite=lax`;
};
// Esta función elimina el locale actual de la ruta
const getRedirectedPath = (locale: string) => {
if (!pathname) return '/';
const segments = pathname.split('/');
segments[1] = locale; // El locale siempre es el primer segmento
return segments.join('/');
};
return (
<div>
{locales.map((locale) => (
<Link
key={locale}
href={getRedirectedPath(locale)}
onClick={() => setLocaleCookie(locale)}
style={{
display: 'inline-block',
padding: '0.5rem',
textDecoration: 'underline',
}}
>
{locale.toUpperCase()}
</Link>
))}
</div>
);
}
3. Añade el selector a tu layout
Importa y coloca tu nuevo componente en el archivo de layout raíz, app/[lang]/layout.tsx. Esto lo hace visible en todas las páginas.
// app/[lang]/layout.tsx
import LanguageSwitcher from '@/app/components/LanguageSwitcher';
export async function generateStaticParams() {
// Esto le dice a Next.js que pre-renderice 'en', 'es', y 'fr'
return [{ lang: 'en' }, { lang: 'es' }, { lang: 'fr' }];
}
export default function RootLayout({
children,
params,
}: {
children: React.ReactNode;
params: { lang: string };
}) {
return (
<html lang={params.lang}>
<body>
<header>
{/* Añade el selector a tu encabezado o navegación */}
<LanguageSwitcher />
</header>
<main>{children}</main>
</body>
</html>
);
}
Ahora, cuando un usuario está en /es/products/123 y hace clic en "EN", el componente calcula la nueva ruta como /en/products/123 y establece la cookie NEXT_LOCALE a 'en'.