Comment lier les versions linguistiques alternatives dans React Router v7

Lier les alternatives linguistiques pour les moteurs de recherche

Problème

Lorsqu'un site web propose le même contenu dans plusieurs langues, les moteurs de recherche sont confrontés à un défi. Sans signaux explicites, ils traitent chaque version linguistique comme une page distincte et non liée. Un utilisateur français effectuant une recherche en français pourrait voir la version anglaise mieux classée que la version française, même si les deux existent. De même, un utilisateur anglais pourrait atterrir sur une page allemande. Cela se produit parce que les moteurs de recherche ne peuvent pas déterminer automatiquement que /en/about et /fr/about sont des traductions l'une de l'autre plutôt que des pages concurrentes avec du contenu dupliqué.

Cette confusion divise l'autorité de classement entre les versions linguistiques et dégrade l'expérience utilisateur. Les moteurs de recherche ont besoin de métadonnées explicites pour comprendre quelles pages sont des alternatives linguistiques du même contenu afin de pouvoir proposer la version appropriée en fonction de la préférence linguistique et de la localisation de chaque utilisateur.

Solution

Ajoutez des balises link hreflang à chaque page qui répertorient toutes les versions linguistiques disponibles de ce contenu. Ces balises utilisent l'attribut rel="alternate" pour signaler que les pages liées sont des traductions, et non des doublons. Chaque balise spécifie un code de langue et pointe vers l'URL de cette version linguistique.

En déclarant ces relations dans les métadonnées de la page, vous aidez les moteurs de recherche à comprendre la structure de votre site et à proposer la version linguistique correcte à chaque utilisateur. Cela améliore la pertinence des résultats de recherche et évite les pénalités pour contenu dupliqué.

Étapes

1. Créer une fonction utilitaire pour générer les liens hreflang

L'attribut hreflang utilise les codes de langue ISO 639-1 suivis optionnellement des codes de région ISO 3166-1 Alpha 2. Créez un utilitaire qui génère des descripteurs de lien pour toutes les versions linguistiques d'une page.

type HreflangLink = {
  tagName: "link";
  rel: "alternate";
  hrefLang: string;
  href: string;
};

export function buildHreflangLinks(
  pathname: string,
  locales: string[],
  baseUrl: string,
): HreflangLink[] {
  return locales.map((locale) => ({
    tagName: "link",
    rel: "alternate",
    hrefLang: locale,
    href: `${baseUrl}/${locale}${pathname}`,
  }));
}

Cette fonction prend le chemin actuel, une liste de locales prises en charge et l'URL de base de votre site, puis renvoie un tableau de descripteurs de liens que la fonction meta peut afficher.

2. Ajouter un lien de secours x-default

La valeur hreflang x-default signale une page par défaut lorsqu'aucune autre page n'est mieux adaptée et ne cible pas une langue ou une locale spécifique. Ajoutez-la pour guider les utilisateurs dont vous ne prenez pas en charge la langue.

export function buildHreflangLinks(
  pathname: string,
  locales: string[],
  baseUrl: string,
  defaultLocale: string,
): HreflangLink[] {
  const links = locales.map((locale) => ({
    tagName: "link",
    rel: "alternate",
    hrefLang: locale,
    href: `${baseUrl}/${locale}${pathname}`,
  }));

  links.push({
    tagName: "link",
    rel: "alternate",
    hrefLang: "x-default",
    href: `${baseUrl}/${defaultLocale}${pathname}`,
  });

  return links;
}

Le lien x-default pointe généralement vers votre version linguistique principale et sert de solution de secours pour les utilisateurs dont les préférences linguistiques ne correspondent à aucune de vos versions linguistiques spécifiques.

3. Exporter les liens hreflang depuis votre fonction meta

La fonction meta peut définir des balises link en fonction des données. Utilisez-la pour renvoyer des liens hreflang pour chaque route.

import type { Route } from "./+types/about";
import { buildHreflangLinks } from "~/utils/hreflang";

const SUPPORTED_LOCALES = ["en", "fr", "de", "es"];
const BASE_URL = "https://example.com";
const DEFAULT_LOCALE = "en";

export function meta({ location }: Route.MetaArgs) {
  const hreflangLinks = buildHreflangLinks(
    location.pathname,
    SUPPORTED_LOCALES,
    BASE_URL,
    DEFAULT_LOCALE,
  );

  return [
    { title: "About Us" },
    { name: "description", content: "Learn about our company" },
    ...hreflangLinks,
  ];
}

La fonction meta renvoie un tableau de descripteurs qui peuvent inclure des objets avec tagName défini sur "link". React Router affiche ces éléments sous forme d'éléments link dans l'en-tête du document.

4. S'assurer que le composant Meta est dans votre layout racine

Le composant Meta affiche toutes les balises meta créées par l'export meta du module de route et doit se trouver à l'intérieur de l'élément head de votre document. Vérifiez que votre layout racine l'inclut.

import { Links, Meta, Outlet, Scripts } from "react-router";

export default function Root() {
  return (
    <html lang="en">
      <head>
        <meta charSet="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1" />
        <Meta />
        <Links />
      </head>
      <body>
        <Outlet />
        <Scripts />
      </body>
    </html>
  );
}

Le composant Meta agrège et affiche tous les descripteurs meta de la route correspondante, y compris les balises link hreflang que vous avez définies à l'étape 3.

5. Adapter le chemin pour les routes préfixées par locale

Si vos routes incluent la locale dans le chemin (comme /en/about), supprimez-la avant de construire les liens hreflang afin que toutes les versions linguistiques pointent vers la même page logique.

export function meta({ location }: Route.MetaArgs) {
  const pathWithoutLocale = location.pathname.replace(/^\/[a-z]{2}(\/|$)/, "/");

  const hreflangLinks = buildHreflangLinks(
    pathWithoutLocale,
    SUPPORTED_LOCALES,
    BASE_URL,
    DEFAULT_LOCALE,
  );

  return [{ title: "About Us" }, ...hreflangLinks];
}

Cela garantit que /en/about, /fr/about et /de/about génèrent tous des liens hreflang pointant vers les URL spécifiques à chaque langue pour le même contenu sous-jacent.