Crear un selector de idioma

Permitir 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 se le redirige a la página de inicio (/fr/) en lugar de a la página del producto correspondiente, interrumpiendo su flujo de trabajo y obligándole a navegar de nuevo.

Solución

Crear un componente cliente que lea la ruta URL actual. Genera una lista de enlaces para todos los demás 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 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();

  // This function sets the cookie
  const setLocaleCookie = (locale: string) => {
    document.cookie = `${localeCookieName}=${locale}; path=/; max-age=31536000; samesite=lax`;
  };

  // This function strips the current locale from the path
  const getRedirectedPath = (locale: string) => {
    if (!pathname) return '/';
    const segments = pathname.split('/');
    segments[1] = locale; // The locale is always the first segment
    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() {
  // This tells Next.js to pre-render 'en', 'es', and '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>
          {/* Add the switcher to your header or nav */}
          <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 en 'en'.