So erstellen Sie eine Sprachumschalter-Komponente in Next.js (Pages Router) v16

Sprachen wechseln und dabei auf derselben Seite bleiben

Problem

Benutzer erwarten, dass Sprachumschalter ihre aktuelle Position beibehalten. Wenn jemand eine Produktseite auf Englisch ansieht und zu Spanisch wechselt, möchte er dieselbe Produktseite auf Spanisch sehen und nicht zur Startseite weitergeleitet werden. Das Brechen dieser Erwartung erzeugt Reibung und zwingt Benutzer, zurück zu navigieren, wo sie waren, was die Erfahrung verschlechtert und möglicherweise dazu führt, dass sie die Aufgabe vollständig abbrechen.

Viele Sprachumschalter-Implementierungen scheitern, weil sie die Sprachauswahl als einfache Navigation behandeln und nicht als Transformation der aktuellen Ansicht. Ohne Zugriff auf die Routing-Informationen der aktuellen Seite kann ein Umschalter nur auf feste Ziele verlinken und verliert dabei den Kontext des Benutzers.

Lösung

Erstellen Sie einen Sprachumschalter, der den Pfadnamen und die Query-Parameter der aktuellen Route aus dem Router liest und dann Links für jede unterstützte Sprache generiert, die diese Routing-Informationen beibehalten und nur das Gebietsschema ändern. Durch Übergabe des Pfadnamens und der Query an die Navigations-API zusammen mit dem Ziel-Gebietsschema stellt der Umschalter sicher, dass Benutzer auf der entsprechenden Seite in der neuen Sprache bleiben.

Schritte

1. Erstellen Sie eine Sprachumschalter-Komponente, die die aktuelle Route liest

Das Router-Objekt stellt die Eigenschaften pathname, asPath, query, locale und locales bereit, die alle Informationen enthalten, die zum Erstellen gebietsschemabewusster Links benötigt werden.

import { useRouter } from "next/router";
import Link from "next/link";

export default function LanguageSwitcher() {
  const router = useRouter();
  const { locale, locales, pathname, asPath, query } = router;

  return (
    <nav>
      {locales?.map((loc) => (
        <Link key={loc} href={{ pathname, query }} as={asPath} locale={loc}>
          {loc.toUpperCase()}
        </Link>
      ))}
    </nav>
  );
}

Die Komponente Link akzeptiert eine locale-Prop, um von dem aktuell aktiven Gebietsschema zu einem anderen zu wechseln. Die Übergabe von pathname und query als Objekt an href bewahrt alle Routing-Informationen einschließlich dynamischer Route-Query-Werte.

2. Aktives Gebietsschema stylen, um visuelles Feedback zu geben

Heben Sie die aktuelle Sprache hervor, damit Benutzer wissen, welches Gebietsschema sie gerade ansehen.

import { useRouter } from "next/router";
import Link from "next/link";

export default function LanguageSwitcher() {
  const router = useRouter();
  const { locale, locales, pathname, asPath, query } = router;

  return (
    <nav>
      {locales?.map((loc) => {
        const isActive = loc === locale;
        return (
          <Link
            key={loc}
            href={{ pathname, query }}
            as={asPath}
            locale={loc}
            style={{
              fontWeight: isActive ? "bold" : "normal",
              textDecoration: isActive ? "none" : "underline",
              marginRight: "1rem",
            }}
          >
            {loc.toUpperCase()}
          </Link>
        );
      })}
    </nav>
  );
}

Durch den Vergleich jedes Gebietsschemas mit dem aktuellen locale-Wert wird die aktive Sprache identifiziert und ein deutliches Styling angewendet, um sie von verfügbaren Alternativen zu unterscheiden.

3. Barrierefreie Labels mit react-intl hinzufügen

Ersetzen Sie Gebietsschemacodes durch lesbare Sprachnamen für bessere Benutzerfreundlichkeit.

import { useRouter } from "next/router";
import { useIntl } from "react-intl";
import Link from "next/link";

const localeNames: Record<string, string> = {
  en: "English",
  es: "Español",
  fr: "Français",
  de: "Deutsch",
};

export default function LanguageSwitcher() {
  const router = useRouter();
  const intl = useIntl();
  const { locale, locales, pathname, asPath, query } = router;

  return (
    <nav
      aria-label={intl.formatMessage({
        id: "languageSwitcher.label",
        defaultMessage: "Select language",
      })}
    >
      {locales?.map((loc) => {
        const isActive = loc === locale;
        return (
          <Link
            key={loc}
            href={{ pathname, query }}
            as={asPath}
            locale={loc}
            aria-current={isActive ? "true" : undefined}
            style={{
              fontWeight: isActive ? "bold" : "normal",
              textDecoration: isActive ? "none" : "underline",
              marginRight: "1rem",
            }}
          >
            {localeNames[loc] || loc}
          </Link>
        );
      })}
    </nav>
  );
}

Der useIntl-Hook bietet Zugriff auf Formatierungsfunktionen zur Übersetzung von UI-Labels. Die aria-label- und aria-current-Attribute verbessern die Barrierefreiheit für Screenreader-Benutzer.