Middleware
Code, der vor der Seite läuft – und deshalb schnell sein muss
Eine middleware.ts läuft vor jeder passenden Anfrage. Gut für Weiterleitungen und grobe Zugangsprüfung – nicht für Datenbankabfragen.
MiddlewareCode, der vor jeder passenden Anfrage läuft – für Weiterleitungen, Sprachen oder Zugriffsschutz.Läuft in einer eingeschränkten Umgebung: kein Datenbankzugriff, keine Node-Module.→ sitzt vor deinen Seiten. Sie darf umleiten, umschreiben oder Kopfzeilen setzen – bevor überhaupt entschieden ist, welche Seite gerendert wird.
import { NextResponse, type NextRequest } from "next/server";
export function middleware(request: NextRequest) {
const angemeldet = request.cookies.has("session");
if (!angemeldet) {
const ziel = new URL("/anmelden", request.url);
ziel.searchParams.set("weiter", request.nextUrl.pathname);
return NextResponse.redirect(ziel);
}
return NextResponse.next();
}
// Nur für diese Adressen – wichtig für die Geschwindigkeit
export const config = {
matcher: ["/konto/:path*", "/admin/:path*"],
}; Ohne ihn läuft die Middleware bei jeder Anfrage – auch für Bilder, Schriften und Skripte. Das kostet bei jedem einzelnen Aufruf Zeit. Schränke immer auf die Adressen ein, um die es wirklich geht.
Was sie kann und was nicht
- +
Umleiten: nicht angemeldet → zur Anmeldung
- +
Sprache oder Region aus der Anfrage ableiten
- +
A/B-Tests: Cookie setzen und intern umschreiben
- +
Kopfzeilen setzen, etwa eine Content-Security-Policy
- −
Datenbankabfragen – die Umgebung kann das gar nicht
- −
Vollständige Rechteprüfung; dafür ist sie zu grob
- −
Schwere Berechnungen – alles hier verzögert jede Anfrage
Sie prüft, ob überhaupt ein Sitzungs-Cookie da ist – nicht, ob es gültig ist und was die Person darf. Die echte Prüfung gehört in die Seite, die Server Action oder den Route Handler. Middleware ist der Türsteher, nicht das Schloss.
Die eingeschränkte Umgebung
Verfügbar: fetch, Web-Crypto, URL, Cookies, Headers
Nicht verfügbar: Node-Module (fs, path), Datenbanktreiber,
lange Laufzeiten
Grund: Middleware läuft in der Edge-Umgebung, nah am Nutzer
und für kurze Aufgaben ausgelegt. Deshalb prüft man in der Middleware höchstens ein signiertes Token – das geht mit Web-Crypto. Alles, was die Datenbank braucht, passiert danach.
Umschreiben statt umleiten
// redirect: Adresse ändert sich sichtbar
return NextResponse.redirect(new URL("/anmelden", request.url));
// rewrite: Adresse bleibt, es wird nur intern etwas anderes gerendert
return NextResponse.rewrite(new URL("/de" + pfad, request.url)); ▸ Genauer erklärt: Sprache aus der Anfrage ableiten optional
const SPRACHEN = ["de", "en"];
export function middleware(request: NextRequest) {
const pfad = request.nextUrl.pathname;
// Schon eine Sprache in der Adresse? Dann nichts tun.
if (SPRACHEN.some((s) => pfad.startsWith("/" + s + "/") || pfad === "/" + s)) {
return NextResponse.next();
}
const wunsch = request.headers.get("accept-language") ?? "";
const sprache = wunsch.startsWith("de") ? "de" : "en";
return NextResponse.redirect(new URL("/" + sprache + pfad, request.url));
}
export const config = {
matcher: ["/((?!_next|api|.*\\.).*)"], // keine Assets, keine API
}; Wer die Sprache aktiv wechselt, will beim nächsten Besuch nicht wieder umgeleitet werden. Üblich ist, die Wahl in einem Cookie zu speichern und dieses in der Middleware vor der Kopfzeile abzufragen.
Sitzt das schon?
4 Fragen zu dieser Lektion. Falsche Antworten landen in deiner Statistik.