Sprachauswahl eines Benutzers speichern
Verwendung eines Cookies zum Speichern einer Auswahl
Problem
Ein Benutzer wählt manuell 'Französisch' auf einer Website aus. Wenn er seinen Browser schließt und später die Hauptadresse der Website eingibt (z. B. example.com), kehrt die Anwendung zu ihrer Standardsprache (z. B. Englisch) oder zur automatisch erkannten Sprache zurück. Dieses Versäumnis, sich die Auswahl zu merken, zwingt den Benutzer dazu, den Sprachumschalter zu finden und seine Sprache bei jedem Start einer neuen Sitzung erneut auszuwählen.
Lösung
Wenn ein Benutzer eine Sprache auswählt, speichern Sie diese Auswahl in einem Cookie. Prüfen Sie in der Middleware, wenn ein Benutzer den Root-Pfad (/) besucht, vor der Prüfung des Accept-Language-Headers auf dieses Cookie. Wenn ein gültiges Cookie gefunden wird, leiten Sie den Benutzer zum Root seiner gewählten Sprache weiter (z. B. /fr), wodurch jede Browser-Standardeinstellung überschrieben wird.
Schritte
1. Sprachkonfiguration definieren
Erstellen Sie eine zentrale Konfigurationsdatei, um Ihre unterstützten Sprachen, eine Standardsprache und den Namen des Cookies zu speichern, das Sie zum Speichern der Benutzerpräferenz verwenden werden.
// i18n.config.ts
export const locales = ['en', 'es', 'fr'];
export const defaultLocale = 'en';
export const localeCookieName = 'NEXT_LOCALE';
2. Einen Sprach-Parser installieren
Sie benötigen weiterhin einen Parser für den Accept-Language-Header, der als Fallback verwendet wird, wenn kein Cookie gesetzt ist.
npm install accept-language-parser
3. Die Middleware erstellen
Erstellen Sie eine middleware.ts-Datei im Root-Verzeichnis Ihres Projekts. Diese Middleware prüft zuerst auf das NEXT_LOCALE-Cookie. Wenn es nicht gefunden wird, greift sie auf die Prüfung des Accept-Language-Headers zurück. Diese Logik gilt nur für Anfragen an den Root-Pfad (/).
// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
import parser from 'accept-language-parser';
import {
locales,
defaultLocale,
localeCookieName,
} from './i18n.config';
function getPreferredLocale(request: NextRequest) {
// 1. Check for the cookie
const cookie = request.cookies.get(localeCookieName);
if (cookie) {
const locale = cookie.value;
if (locales.includes(locale)) {
return locale;
}
}
// 2. Check the Accept-Language header
const acceptLang = request.headers.get('Accept-Language');
if (acceptLang) {
const bestMatch = parser.pick(locales, acceptLang, {
loose: true,
});
if (bestMatch) {
return bestMatch;
}
}
// 3. Return the default
return defaultLocale;
}
export function middleware(request: NextRequest) {
const { pathname } = request.nextUrl;
// 1. Check if the request is for the root path
if (pathname === '/') {
// Get the user's preferred language (from cookie or header)
const bestLocale = getPreferredLocale(request);
// Redirect to the best-matched language path
request.nextUrl.pathname = `/${bestLocale}`;
return NextResponse.redirect(request.nextUrl);
}
// 2. For all other paths, continue as normal
return NextResponse.next();
}
export const config = {
matcher: [
// We only want to run this on the root path for now
'/',
// We also need to match non-root paths to let them pass
'/((?!api|_next/static|_next/image|favicon.ico).*)',
],
};
Die Logik dieser Middleware priorisiert nun korrekt die explizite Wahl des Benutzers (das Cookie) gegenüber seiner impliziten Präferenz (dem Browser-Header), wenn er die Startseite der Website besucht.