Next.js 16 Middleware 2026: Edge Runtime, Authentifizierung und Interview-Fragen

Umfassender Leitfaden zu Next.js 16 Middleware mit Edge Runtime, Authentifizierungsmustern, URL-Rewriting und häufigen technischen Interview-Fragen für Frontend-Entwickler.

Next.js 16 Middleware Edge Runtime und Authentifizierung

Next.js 16 Middleware wird vor jeder Anfrage ausgeführt, bevor sie den Server erreicht, und bildet damit die erste Verteidigungslinie für Authentifizierung, Lokalisierung und Request-Manipulation. Das Verständnis von Middleware ist essenziell für den Aufbau produktionsreifer Anwendungen und ein häufiges Thema in Frontend-Interviews.

Middleware läuft am Edge

Next.js 16 Middleware wird standardmäßig in der Edge Runtime ausgeführt, was bedeutet, dass sie in Rechenzentren nahe der Nutzer mit Sub-Millisekunden-Kaltstarts läuft. Das macht sie ideal für Authentifizierungsprüfungen und Weiterleitungen, die vor dem Rendern der Seite erfolgen müssen.

Wie Next.js 16 Middleware unter der Haube funktioniert

Middleware in Next.js 16 fängt Anfragen ab, bevor sie den Route-Handler oder die Page-Komponente erreichen. Die Middleware-Datei muss im Projektstammverzeichnis platziert werden (neben app/ oder pages/) und exportiert eine Standardfunktion, die ein NextRequest-Objekt erhält.

Die Edge Runtime-Einschränkung bedeutet, dass Middleware keine Node.js-APIs wie fs oder Buffer verwenden kann. Sie läuft auf V8-Isolates, ähnlich wie Cloudflare Workers, was globale Verteilung ermöglicht, aber die verfügbaren APIs auf Web-Standards beschränkt.

middleware.tstypescript
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export function middleware(request: NextRequest) {
  // Access request headers, cookies, and URL
  const token = request.cookies.get('session')?.value
  const pathname = request.nextUrl.pathname

  // Log for debugging (visible in Vercel logs)
  console.log(`Middleware: ${request.method} ${pathname}`)

  // Continue to the route handler
  return NextResponse.next()
}

// Configure which paths trigger middleware
export const config = {
  matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)'],
}

Die matcher-Konfiguration verwendet eine Regex-ähnliche Syntax, um zu definieren, welche Pfade die Middleware auslösen. Ohne sie läuft die Middleware bei jeder Anfrage, einschließlich statischer Assets.

Authentifizierungsmuster mit Next.js Middleware

Middleware eignet sich hervorragend für Authentifizierung, da sie vor jeglichem Seitencode ausgeführt wird. Ein Nutzer ohne gültige Sitzung sieht geschützte Inhalte nie, auch nicht kurzzeitig. Das unterscheidet sich von clientseitigen Auth-Prüfungen, die geschützte Inhalte kurz aufblitzen lassen können, bevor sie weiterleiten.

Das folgende Muster validiert einen Sitzungstoken und leitet nicht authentifizierte Nutzer weiter. Es lässt sich mit jedem Auth-Provider integrieren, der Sitzungsdaten in Cookies oder Headers speichert.

middleware.tstypescript
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

const protectedPaths = ['/dashboard', '/settings', '/profile']
const authPaths = ['/login', '/signup']

export async function middleware(request: NextRequest) {
  const { pathname } = request.nextUrl
  const sessionToken = request.cookies.get('session')?.value

  // Check if path requires authentication
  const isProtectedPath = protectedPaths.some(path => 
    pathname.startsWith(path)
  )
  const isAuthPath = authPaths.some(path => 
    pathname.startsWith(path)
  )

  // Validate session token (call auth service)
  const isValidSession = sessionToken 
    ? await validateSession(sessionToken)
    : false

  // Redirect unauthenticated users to login
  if (isProtectedPath && !isValidSession) {
    const loginUrl = new URL('/login', request.url)
    loginUrl.searchParams.set('callbackUrl', pathname)
    return NextResponse.redirect(loginUrl)
  }

  // Redirect authenticated users away from auth pages
  if (isAuthPath && isValidSession) {
    return NextResponse.redirect(new URL('/dashboard', request.url))
  }

  return NextResponse.next()
}

async function validateSession(token: string): Promise<boolean> {
  // Call auth API endpoint or decode JWT
  // Edge-compatible: use fetch, not Node.js crypto
  try {
    const response = await fetch('https://api.example.com/validate', {
      headers: { Authorization: `Bearer ${token}` },
    })
    return response.ok
  } catch {
    return false
  }
}

Der callbackUrl-Parameter bewahrt das ursprüngliche Ziel, sodass Nutzer nach dem Einloggen auf der ursprünglich angeforderten Seite landen.

Pfad-Matching und die Matcher-Konfiguration

Die matcher-Konfiguration bestimmt, welche Anfragen die Middleware auslösen. Fehler hier führen zu Performance-Problemen (Middleware läuft bei jedem statischen Asset) oder Sicherheitslücken (geschützte Pfade lösen keine Auth-Prüfungen aus).

Next.js 16 unterstützt drei Matcher-Syntaxen: String-Pfade, Pfadmuster mit Parametern und Regex-ähnliche Muster mit negativen Lookaheads.

middleware.tstypescript
// Option 1: Simple string paths
export const config = {
  matcher: ['/dashboard/:path*', '/api/:path*'],
}

// Option 2: Exclude static assets with negative lookahead
export const config = {
  matcher: ['/((?!_next/static|_next/image|favicon.ico|public/).*)'],
}

// Option 3: Conditional matching with has/missing
export const config = {
  matcher: [
    {
      source: '/api/:path*',
      has: [{ type: 'header', key: 'Authorization' }],
    },
    {
      source: '/dashboard/:path*',
      missing: [{ type: 'cookie', key: 'session' }],
    },
  ],
}

Die has- und missing-Bedingungen in Option 3 fügen Logik hinzu, bevor die Middleware überhaupt ausgeführt wird. Das ist effizienter als die Prüfung innerhalb der Middleware-Funktion.

Bereit für deine React / Next.js-Interviews?

Übe mit unseren interaktiven Simulatoren, Flashcards und technischen Tests.

Request- und Response-Manipulation in Middleware

Über Authentifizierung hinaus kann Middleware Anfragen modifizieren, bevor sie Route-Handler erreichen, und Antworten, bevor sie den Client erreichen. Häufige Anwendungsfälle sind das Hinzufügen von Sicherheits-Headern, URL-Rewrites für A/B-Tests und das Injizieren von Geolokalisierungsdaten.

Die NextResponse-Klasse bietet Methoden für jeden Modifikationstyp. Rewrites ändern das Ziel ohne Änderung der Browser-URL, während Redirects beides aktualisieren.

middleware.tstypescript
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export function middleware(request: NextRequest) {
  const response = NextResponse.next()

  // Add security headers to all responses
  response.headers.set('X-Frame-Options', 'DENY')
  response.headers.set('X-Content-Type-Options', 'nosniff')
  response.headers.set(
    'Referrer-Policy', 
    'strict-origin-when-cross-origin'
  )

  // Inject geolocation into request headers for route handlers
  const geo = request.geo
  if (geo?.country) {
    response.headers.set('x-user-country', geo.country)
    response.headers.set('x-user-city', geo.city ?? 'unknown')
  }

  return response
}

Geolokalisierungsdaten (request.geo) werden vom Vercel Edge Network befüllt. Selbst gehostete Deployments müssen dies über den Hosting-Provider konfigurieren oder einen Drittanbieter-IP-Geolokalisierungsdienst verwenden.

URL-Rewriting für A/B-Tests und Feature Flags

Middleware-Rewrites ermöglichen es, verschiedene Seiten basierend auf Cookies, Headers oder zufälliger Zuweisung zu liefern, ohne dass der Client es weiß. Dieses Muster treibt A/B-Testing-Frameworks und schrittweise Feature-Rollouts an.

Das Rewrite findet am Edge statt, sodass beide Varianten dieselbe URL haben und gegebenenfalls vom Edge-Caching profitieren.

middleware.tstypescript
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export function middleware(request: NextRequest) {
  const { pathname } = request.nextUrl

  // Check for existing variant assignment
  let variant = request.cookies.get('ab-variant')?.value

  // Assign variant if not set (50/50 split)
  if (!variant && pathname === '/pricing') {
    variant = Math.random() < 0.5 ? 'control' : 'treatment'
    const response = NextResponse.rewrite(
      new URL(`/pricing/${variant}`, request.url)
    )
    response.cookies.set('ab-variant', variant, {
      maxAge: 60 * 60 * 24 * 30, // 30 days
      httpOnly: true,
    })
    return response
  }

  // Rewrite to assigned variant
  if (variant && pathname === '/pricing') {
    return NextResponse.rewrite(
      new URL(`/pricing/${variant}`, request.url)
    )
  }

  return NextResponse.next()
}

Das Cookie persistiert die Variantenzuweisung und stellt sicher, dass Nutzer bei Rückkehrbesuchen dieselbe Version sehen. Die 30-tägige Ablaufzeit balanciert Experimentkonsistenz mit der Möglichkeit, Nutzer neuen Experimenten zuzuweisen.

Edge Runtime-Einschränkungen und Workarounds

Die Edge Runtime tauscht Node.js-Kompatibilität gegen globale Verteilung und schnelle Kaltstarts ein. Middleware kann keine Node.js-spezifischen Module importieren, was Bibliotheken wie bcrypt, jsonwebtoken (bei Verwendung von RS256) und Datenbank-Clients betrifft, die auf TCP-Sockets angewiesen sind.

Die Next.js Edge Runtime-Dokumentation listet unterstützte APIs auf. Web Crypto, fetch und die meisten Web-Platform-APIs funktionieren. Aufwändige Berechnungen sollten in API-Routes verschoben werden, die in Node.js laufen.

middleware.ts - JWT validation without jsonwebtokentypescript
import { jwtVerify } from 'jose' // Edge-compatible JWT library
import type { NextRequest } from 'next/server'

const JWT_SECRET = new TextEncoder().encode(process.env.JWT_SECRET!)

export async function middleware(request: NextRequest) {
  const token = request.cookies.get('token')?.value

  if (!token) {
    return redirectToLogin(request)
  }

  try {
    // jose library works in Edge Runtime
    const { payload } = await jwtVerify(token, JWT_SECRET)
    
    // Token is valid, check expiration
    if (payload.exp && payload.exp < Date.now() / 1000) {
      return redirectToLogin(request)
    }

    return NextResponse.next()
  } catch {
    // Invalid token signature or format
    return redirectToLogin(request)
  }
}

function redirectToLogin(request: NextRequest) {
  const url = new URL('/login', request.url)
  url.searchParams.set('callbackUrl', request.nextUrl.pathname)
  return NextResponse.redirect(url)
}

Die jose-Bibliothek bietet Edge-kompatible JWT-Operationen. Sie nutzt Web Crypto unter der Haube und vermeidet das Node.js-crypto-Modul.

Häufige Next.js Middleware Interview-Fragen

Interviewer fragen nach Middleware, um das Verständnis des Request-Lifecycles, von Sicherheitsmustern und Edge-Computing-Einschränkungen zu bewerten. Diese Fragen erscheinen in Senior-Frontend- und Fullstack-Rollen, die mit Next.js arbeiten.

Wo wird Middleware im Request-Lifecycle ausgeführt?

Middleware läuft, nachdem die Anfrage den Next.js-Server erreicht hat, aber bevor irgendein Route-Matching oder Page-Rendering stattfindet. Auf Vercel wird sie am Edge ausgeführt, also im nächstgelegenen Rechenzentrum zum Nutzer. Diese Platzierung macht sie ideal für Authentifizierung und Redirects, da ungültige Anfragen nie den Origin-Server erreichen.

Was kann Middleware im Vergleich zu API-Routes nicht?

Middleware läuft in der Edge Runtime, nicht in Node.js. Sie kann keine eingebauten Node.js-Module (fs, path, crypto mit bestimmten Algorithmen), TCP-basierte Datenbank-Clients oder npm-Pakete verwenden, die von Node.js-APIs abhängen. Aufwändige Berechnungen sollten in API-Routes oder Server Components erfolgen.

Wie handhabt man Authentifizierung in Middleware ohne Blockierung?

Das Muster beinhaltet die Prüfung auf ein Sitzungs-Cookie, dessen Validierung gegen einen Auth-Endpunkt oder durch Verifizierung einer JWT-Signatur, und Weiterleitung bei Ungültigkeit. Um zu vermeiden, dass jede Anfrage blockiert wird, verwendet man die matcher-Konfiguration, um Middleware nur auf geschützten Pfaden auszuführen. Zustandslose JWT-Validierung ist schneller als der Aufruf eines externen Auth-Services bei jeder Anfrage.

Was passiert, wenn Middleware einen Fehler wirft?

Ein nicht behandelter Fehler in Middleware gibt eine 500-Antwort an den Client zurück. Die Seite wird nie gerendert. Das Umschließen der Middleware-Logik in try-catch und das Zurückgeben einer Fallback-Antwort (oft NextResponse.next()) verhindert komplette Request-Ausfälle. Das Loggen des Fehlers vor dem Fortfahren hilft beim Debugging.

Für vertiefende Praxis mit diesen Konzepten behandelt das Next.js Middleware und Auth Interview-Fragen-Modul zusätzliche Szenarien.

Debugging von Middleware in Entwicklung und Produktion

Middleware-Bugs sind knifflig, da der Code am Edge läuft, nicht in den Browser DevTools. Der Entwicklungsmodus zeigt Middleware-Logs im Terminal, aber Produktion erfordert eine ordentliche Logging-Infrastruktur.

Der folgende Ansatz loggt die Middleware-Ausführung mit genügend Kontext zum Debuggen von Problemen, ohne sensible Daten preiszugeben.

middleware.tstypescript
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export function middleware(request: NextRequest) {
  const start = Date.now()
  const requestId = crypto.randomUUID()

  // Log request start
  console.log(JSON.stringify({
    type: 'middleware_request',
    requestId,
    method: request.method,
    path: request.nextUrl.pathname,
    userAgent: request.headers.get('user-agent')?.slice(0, 100),
    country: request.geo?.country,
  }))

  // Process request
  const response = processRequest(request)

  // Log completion
  console.log(JSON.stringify({
    type: 'middleware_response',
    requestId,
    duration: Date.now() - start,
    status: response.status,
  }))

  // Pass request ID to route handlers
  response.headers.set('x-request-id', requestId)
  return response
}

function processRequest(request: NextRequest): NextResponse {
  // Middleware logic here
  return NextResponse.next()
}

Auf Vercel erscheinen diese Logs im Functions-Tab. Selbst gehostete Deployments sollten Logs an einen Dienst wie Datadog senden oder strukturiertes Logging verwenden, das die Hosting-Plattform verarbeiten kann.

Middleware Performance Best Practices

Middleware läuft bei jeder gematchten Anfrage. Eine langsame Middleware-Funktion fügt jedem Seitenaufruf Latenz hinzu. Das Ziel ist, die Middleware-Ausführung für die meisten Anfragen in unter 5ms abzuschließen.

  • Async-Operationen minimieren: Jedes await fügt Latenz hinzu. Validierungsergebnisse wo möglich cachen.
  • Matcher-Config verwenden: Statische Assets und öffentliche Pfade ausschließen, die keine Middleware-Logik benötigen.
  • Externe Aufrufe bei jeder Anfrage vermeiden: JWTs lokal validieren statt einen Auth-Service aufzurufen. Ergebnisse in Cookies cachen wenn angemessen.
  • Bundle klein halten: Middleware hat ein eigenes Bundle-Size-Limit (1MB auf Vercel). Nur importieren, was benötigt wird.

Die React Next.js Technologie-Seite unter /technologies/react-next behandelt verwandte Konzepte wie Server Components und Data-Fetching-Muster, die das Middleware-Wissen ergänzen.

Fang an zu üben!

Teste dein Wissen mit unseren Interview-Simulatoren und technischen Tests.

Next.js 16 Middleware Checkliste für Produktion

  • Middleware im Projektstammverzeichnis als middleware.ts platzieren, nicht innerhalb von app/ oder pages/
  • Den matcher so konfigurieren, dass _next/static, _next/image und öffentliche Assets von der Middleware-Ausführung ausgeschlossen werden
  • Edge-kompatible Bibliotheken für JWT-Validierung verwenden, wie jose statt jsonwebtoken
  • Callback-URLs in Query-Parametern speichern, wenn zum Login weitergeleitet wird, damit Nutzer zu ihrem beabsichtigten Ziel zurückkehren
  • Sicherheits-Header in Middleware hinzufügen für konsistente Anwendung über alle Routen
  • Middleware-Ausführung mit Request-IDs loggen, um Anfragen durch das System zu verfolgen
  • Externe API-Aufrufe minimieren durch lokale Token-Validierung und Caching von Nutzerdaten in signierten Cookies
Tägliche Challenge

Findest du den Bug in React / Next.js?

Ein echter Codeausschnitt, ein versteckter Bug, ein Versuch pro Tag. Zum Ausprobieren ohne Konto.

Anthony Fillion-Maillet

Geschrieben von

Anthony Fillion-Maillet

Gründer von SharpSkill

Seit über 10 Jahren Fullstack-Entwickler. Er leitet SharpSkill und verantwortet alles, was hier erscheint.

Aktualisiert am 20. September 2026

Tags

#nextjs
#middleware
#edge-runtime
#authentication
#interview

Teilen

Verwandte Artikel