So verknüpfen Sie alternative Sprachversionen in React Router v7

Verknüpfen Sie Sprachalternativen für Suchmaschinen

Problem

Wenn eine Website denselben Inhalt in mehreren Sprachen bereitstellt, stehen Suchmaschinen vor einer Herausforderung. Ohne explizite Signale behandeln sie jede Sprachversion als separate, unabhängige Seite. Ein französischer Nutzer, der auf Französisch sucht, könnte die englische Version höher eingestuft sehen als die französische Version, obwohl beide existieren. Ebenso könnte ein englischer Nutzer auf einer deutschen Seite landen. Dies geschieht, weil Suchmaschinen nicht automatisch erkennen können, dass /en/about und /fr/about Übersetzungen voneinander sind und nicht konkurrierende Seiten mit doppeltem Inhalt.

Diese Verwirrung teilt die Ranking-Autorität zwischen Sprachversionen auf und beeinträchtigt die Nutzererfahrung. Suchmaschinen benötigen explizite Metadaten, um zu verstehen, welche Seiten Sprachalternativen desselben Inhalts sind, damit sie die entsprechende Version basierend auf der Sprachpräferenz und dem Standort jedes Nutzers bereitstellen können.

Lösung

Fügen Sie hreflang Link-Tags zu jeder Seite hinzu, die alle verfügbaren Sprachversionen dieses Inhalts auflisten. Diese Tags verwenden das rel="alternate" Attribut, um zu signalisieren, dass die verlinkten Seiten Übersetzungen und keine Duplikate sind. Jedes Tag gibt einen Sprachcode an und verweist auf die URL für diese Sprachversion.

Indem Sie diese Beziehungen in den Seiten-Metadaten deklarieren, helfen Sie Suchmaschinen, Ihre Website-Struktur zu verstehen und die korrekte Sprachversion für jeden Nutzer bereitzustellen. Dies verbessert die Relevanz der Suchergebnisse und verhindert Strafen für doppelte Inhalte.

Schritte

Das hreflang-Attribut verwendet ISO 639-1 Sprachcodes, optional gefolgt von ISO 3166-1 Alpha 2 Regionscodes. Erstellen Sie ein Utility, das Link-Deskriptoren für alle Sprachversionen einer Seite generiert.

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}`,
  }));
}

Diese Funktion nimmt den aktuellen Pfadnamen, eine Liste der unterstützten Locales und die Basis-URL Ihrer Website entgegen und gibt ein Array von Link-Deskriptoren zurück, die die Meta-Funktion rendern kann.

Der x-default-hreflang-Wert signalisiert eine Standardseite, wenn keine andere Seite besser geeignet ist und keine bestimmte Sprache oder Locale anspricht. Fügen Sie dies hinzu, um Benutzer zu leiten, deren Sprache Sie nicht unterstützen.

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

Der x-default-Link verweist typischerweise auf Ihre primäre Sprachversion und dient als Fallback für Benutzer, deren Sprachpräferenzen mit keiner Ihrer spezifischen Sprachversionen übereinstimmen.

Die Meta-Funktion kann Link-Tags basierend auf Daten setzen. Verwenden Sie sie, um hreflang-Links für jede Route zurückzugeben.

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,
  ];
}

Die Meta-Funktion gibt ein Array von Deskriptoren zurück, das Objekte mit tagName auf "link" gesetzt enthalten kann. React Router rendert diese als Link-Elemente im Document-Head.

4. Stellen Sie sicher, dass die Meta-Komponente in Ihrem Root-Layout enthalten ist

Die Meta-Komponente rendert alle Meta-Tags, die durch den Meta-Export des Route-Moduls erstellt wurden, und sollte sich im Head Ihres Dokuments befinden. Überprüfen Sie, ob Ihr Root-Layout diese enthält.

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

Die Meta-Komponente aggregiert und rendert alle Meta-Deskriptoren aus der gematchten Route, einschließlich der hreflang-Link-Tags, die Sie in Schritt 3 definiert haben.

5. Passen Sie den Pfadnamen für Locale-präfixierte Routen an

Wenn Ihre Routen die Locale im Pfad enthalten (wie /en/about), entfernen Sie diese, bevor Sie hreflang-Links erstellen, damit alle Sprachversionen auf dieselbe logische Seite verweisen.

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];
}

Dies stellt sicher, dass /en/about, /fr/about und /de/about alle hreflang-Links generieren, die auf die korrekten sprachspezifischen URLs für denselben zugrunde liegenden Inhalt verweisen.