Liens entre pages localisées

Maintenir les utilisateurs dans leur langue sélectionnée

Problème

Lorsque les codes de langue font partie de l'URL, la création de liens internes devient complexe. Un simple lien comme <a href="/about"> est incorrect, car il rompt la route localisée, envoyant un utilisateur de /fr/contact vers /about au lieu de /fr/about. Cela fait sortir l'utilisateur de la langue qu'il a sélectionnée.

Solution

Créer un composant personnalisé qui enveloppe le composant Link de Next.js. Ce nouveau composant utilisera le hook useParams pour obtenir la langue actuelle depuis l'URL et l'ajoutera automatiquement en préfixe à tout href qu'il reçoit, garantissant ainsi que tous les liens internes sont correctement localisés.

Étapes

Créez un nouveau fichier app/components/LocalizedLink.tsx. Ce doit être un composant client pour utiliser le 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} />;
}

Ce composant importe les props standard de Link. Il vérifie si href est une chaîne de caractères (comme /about) ou un objet (comme { pathname: '/about' }) et ajoute intelligemment la lang courante (par exemple, es) en préfixe.

2. Utilisez le composant dans vos pages

Maintenant, dans vos pages, importez LocalizedLink au lieu du standard next/link. Vous pouvez l'utiliser exactement comme vous utiliseriez le composant Link normal, mais sans vous soucier du préfixe de langue.

// 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>
  );
}

L'utilisation de <LocalizedLink href="/about"> génère maintenant correctement un lien vers /{current_lang}/about, maintenant l'utilisateur dans la langue qu'il a sélectionnée lorsqu'il navigue sur votre site.