Enlazar entre páginas localizadas
Mantener a los usuarios en su idioma seleccionado
Problema
Cuando los códigos de idioma forman parte de la URL, crear enlaces internos se vuelve complejo. Un enlace simple como <a href="/about"> es incorrecto, ya que rompe la ruta localizada, enviando a un usuario de /fr/contact a /about en lugar de /fr/about. Esto saca al usuario de su idioma seleccionado.
Solución
Crear un componente personalizado envolvente alrededor del componente Link de Next.js. Este nuevo componente utilizará el hook useParams para obtener el idioma actual de la URL y anteponerlo automáticamente a cualquier href que reciba, asegurando que todos los enlaces internos estén correctamente localizados.
Pasos
1. Crear un componente LocalizedLink
Crear un nuevo archivo app/components/LocalizedLink.tsx. Este debe ser un componente cliente para usar el hook useParams.
// app/components/LocalizedLink.tsx
'use client';
import Link from 'next/link';
import { useParams } from 'next/navigation';
import type { ComponentProps } from 'react';
type LinkProps = ComponentProps<typeof Link>;
export default function LocalizedLink({ href, ...rest }: LinkProps) {
const params = useParams();
const lang = params.lang as string;
let localizedHref = href;
// Check if href is a string and needs prefixing
if (typeof href === 'string' && href.startsWith('/')) {
localizedHref = `/${lang}${href}`;
} else if (
typeof href === 'object' &&
href !== null &&
href.pathname?.startsWith('/')
) {
// Re-create the object with a prefixed pathname
localizedHref = {
...href,
pathname: `/${lang}${href.pathname}`,
};
}
// Absolute URLs or other cases are passed through
return <Link href={localizedHref} {...rest} />;
}
Este componente importa las props estándar de Link. Verifica si href es una cadena (como /about) o un objeto (como { pathname: '/about' }) y antepone inteligentemente el lang actual (por ejemplo, es) a él.
2. Usar el componente en tus páginas
Ahora, en tus páginas, importa LocalizedLink en lugar del next/link estándar. Puedes usarlo tal como usarías el componente Link normal, pero sin preocuparte por el prefijo de idioma.
// app/[lang]/page.tsx
import LocalizedLink from '@/app/components/LocalizedLink';
export default function Home({ params }: { params: { lang: string } }) {
return (
<div>
<h1>Home page</h1>
<p>Current language: {params.lang}</p>
<nav>
<ul>
<li>
{/* This will render as /en/about or /es/about, etc. */}
<LocalizedLink href="/about">About page</LocalizedLink>
</li>
<li>
{/* This also works */}
<LocalizedLink href={{ pathname: '/contact' }}>
Contact page
</LocalizedLink>
</li>
</ul>
</nav>
</div>
);
}
Usar <LocalizedLink href="/about"> ahora renderiza correctamente un enlace a /{current_lang}/about, manteniendo al usuario dentro de su idioma seleccionado mientras navega por tu sitio.