Comment traduire les métadonnées de page dans React Router v7

Traduire les métadonnées pour la recherche et les réseaux sociaux

Problème

Les métadonnées de page—titres et descriptions—apparaissent en dehors de la page elle-même, dans les onglets du navigateur, les favoris, les résultats de recherche et les aperçus sur les réseaux sociaux. Lorsque ces métadonnées ne correspondent pas à la langue de la page, cela crée une incohérence discordante. Une page en espagnol avec un titre en anglais désoriente les utilisateurs avant même qu'ils ne voient le contenu. Les moteurs de recherche interprètent cette discordance comme un signal indiquant que la page est mal localisée ou de faible qualité, ce qui peut réduire son classement dans les résultats spécifiques à une langue. Les utilisateurs peuvent abandonner la page avant qu'elle ne se charge, supposant qu'elle n'est pas dans leur langue.

Solution

Traduisez les métadonnées de page pour qu'elles correspondent à la langue actuelle en exportant une fonction meta depuis votre module de route. Utilisez l'API formatMessage de react-intl avec des Message Descriptors pour traduire les chaînes de titre et de description, garantissant ainsi que les métadonnées utilisent les mêmes ressources de traduction que le contenu de la page. Cela maintient la cohérence entre ce qui s'affiche dans les onglets du navigateur, les résultats de recherche et la page elle-même.

Étapes

1. Créer un assistant pour accéder à intl en dehors des composants

L'objet intl fournit formatMessage et peut être accessible via le hook useIntl dans les composants ou créé directement avec createIntl dans des environnements non-React. Comme la fonction meta s'exécute en dehors de l'arborescence des composants React, créez un assistant qui construit une instance intl à partir de vos messages.

import { createIntl, createIntlCache } from "react-intl";

const cache = createIntlCache();

export function createIntlForLocale(
  locale: string,
  messages: Record<string, string>,
) {
  return createIntl(
    {
      locale,
      messages,
    },
    cache,
  );
}

Cet assistant crée une instance intl qui peut formater des messages dans n'importe quelle fonction, pas seulement dans les composants React.

2. Charger les messages dans un chargeur de route parent

Les chargeurs de route renvoient des données auxquelles les composants accèdent via les props loaderData. Chargez vos messages de traduction dans une route parente afin qu'ils soient disponibles pour les routes enfants.

import type { Route } from "./+types/root";

export async function loader({ request }: Route.LoaderArgs) {
  const url = new URL(request.url);
  const locale = url.pathname.split("/")[1] || "en";

  const messages = await import(`../translations/${locale}.json`);

  return {
    locale,
    messages: messages.default,
  };
}

La fonction meta reçoit un paramètre matches contenant les données du chargeur de toutes les routes correspondantes, rendant les données du chargeur parent accessibles aux fonctions meta des routes enfants.

3. Exportez une fonction meta qui traduit les métadonnées

Exportez une fonction meta depuis votre module de route qui renvoie un tableau d'objets descripteurs meta. Accédez aux données du chargeur parent à partir de matches et utilisez votre assistant intl pour traduire les chaînes.

import type { Route } from "./+types/product";
import { createIntlForLocale } from "~/utils/intl";

export function meta({ matches }: Route.MetaArgs) {
  const rootMatch = matches.find((match) => match.id === "root");
  const { locale, messages } = rootMatch?.data || {
    locale: "en",
    messages: {},
  };

  const intl = createIntlForLocale(locale, messages);

  return [
    {
      title: intl.formatMessage({
        id: "product.meta.title",
        defaultMessage: "Product Details",
      }),
    },
    {
      name: "description",
      content: intl.formatMessage({
        id: "product.meta.description",
        defaultMessage: "View detailed information about this product",
      }),
    },
  ];
}

La fonction formatMessage accepte un descripteur de message avec un id et un defaultMessage, renvoyant la chaîne traduite pour la locale actuelle.

4. Ajoutez des chaînes de métadonnées traduites à vos fichiers de messages

Ajoutez les clés de traduction des métadonnées à chaque fichier de messages de locale afin que formatMessage puisse les trouver.

{
  "product.meta.title": "Détails du produit",
  "product.meta.description": "Voir les informations détaillées sur ce produit"
}

Lorsque les utilisateurs naviguent vers cette route, le composant Meta dans votre mise en page racine rend toutes les balises meta créées par les exports meta de route, affichant des titres et descriptions traduits qui correspondent à la langue de la page.