Weiterleitungen
Es gibt mehrere Möglichkeiten, Weiterleitungen in Next.js zu handhaben. Diese Seite stellt jede verfügbare Option vor, erläutert Anwendungsfälle und zeigt, wie Sie eine große Anzahl von Weiterleitungen verwalten können.
API | Zweck | Verwendungsort | Statuscode |
---|---|---|---|
redirect | Benutzer nach Mutation oder Ereignis umleiten | Server Components, Server Actions, Route Handlers | 307 (Temporär) oder 303 (Server Action) |
permanentRedirect | Benutzer dauerhaft umleiten | Server Components, Server Actions, Route Handlers | 308 (Permanent) |
useRouter | Client-seitige Navigation durchführen | Event Handler in Client Components | N/A |
redirects in next.config.js | Anfrage basierend auf Pfad umleiten | next.config.js Datei | 307 (Temporär) oder 308 (Permanent) |
NextResponse.redirect | Anfrage basierend auf Bedingung umleiten | Middleware | Beliebig |
redirect
-Funktion
Die redirect
-Funktion ermöglicht es, Benutzer auf eine andere URL umzuleiten. Sie können redirect
in Server Components, Route Handlers und Server Actions aufrufen.
redirect
wird häufig nach einer Mutation oder einem Ereignis verwendet. Zum Beispiel beim Erstellen eines Posts:
'use server'
import { redirect } from 'next/navigation'
import { revalidatePath } from 'next/cache'
export async function createPost(id: string) {
try {
// Datenbank aufrufen
} catch (error) {
// Fehler behandeln
}
revalidatePath('/posts') // Cache aktualisieren
redirect(`/post/${id}`) // Zur neuen Post-Seite navigieren
}
'use server'
import { redirect } from 'next/navigation'
import { revalidatePath } from 'next/cache'
export async function createPost(id) {
try {
// Datenbank aufrufen
} catch (error) {
// Fehler behandeln
}
revalidatePath('/posts') // Cache aktualisieren
redirect(`/post/${id}`) // Zur neuen Post-Seite navigieren
}
Gut zu wissen:
redirect
gibt standardmäßig einen 307 (Temporary Redirect) Statuscode zurück. Bei Verwendung in einer Server Action wird ein 303 (See Other) zurückgegeben, der häufig für Weiterleitungen nach POST-Anfragen verwendet wird.redirect
wirft intern einen Fehler und sollte daher außerhalb vontry/catch
-Blöcken aufgerufen werden.redirect
kann in Client Components während des Rendering-Prozesses aufgerufen werden, aber nicht in Event Handlern. Verwenden Sie stattdessen denuseRouter
-Hook.redirect
akzeptiert auch absolute URLs und kann für externe Links verwendet werden.- Für Weiterleitungen vor dem Rendering-Prozess verwenden Sie
next.config.js
oder Middleware.
Weitere Informationen finden Sie in der redirect
-API-Referenz.
permanentRedirect
-Funktion
Die permanentRedirect
-Funktion ermöglicht es, Benutzer dauerhaft auf eine andere URL umzuleiten. Sie können permanentRedirect
in Server Components, Route Handlers und Server Actions aufrufen.
permanentRedirect
wird häufig nach Mutationen verwendet, die die kanonische URL einer Entität ändern, z.B. beim Aktualisieren eines Profil-URLs nach einer Namensänderung:
'use server'
import { permanentRedirect } from 'next/navigation'
import { revalidateTag } from 'next/cache'
export async function updateUsername(username: string, formData: FormData) {
try {
// Datenbank aufrufen
} catch (error) {
// Fehler behandeln
}
revalidateTag('username') // Referenzen aktualisieren
permanentRedirect(`/profile/${username}`) // Zum neuen Profil navigieren
}
'use server'
import { permanentRedirect } from 'next/navigation'
import { revalidateTag } from 'next/cache'
export async function updateUsername(username, formData) {
try {
// Datenbank aufrufen
} catch (error) {
// Fehler behandeln
}
revalidateTag('username') // Referenzen aktualisieren
permanentRedirect(`/profile/${username}`) // Zum neuen Profil navigieren
}
Gut zu wissen:
permanentRedirect
gibt standardmäßig einen 308 (Permanent Redirect) Statuscode zurück.permanentRedirect
akzeptiert auch absolute URLs und kann für externe Links verwendet werden.- Für Weiterleitungen vor dem Rendering-Prozess verwenden Sie
next.config.js
oder Middleware.
Weitere Informationen finden Sie in der permanentRedirect
-API-Referenz.
useRouter()
-Hook
Für Weiterleitungen in Event Handlern von Client Components können Sie die push
-Methode des useRouter
-Hooks verwenden. Beispiel:
'use client'
import { useRouter } from 'next/navigation'
export default function Page() {
const router = useRouter()
return (
<button type="button" onClick={() => router.push('/dashboard')}>
Dashboard
</button>
)
}
'use client'
import { useRouter } from 'next/navigation'
export default function Page() {
const router = useRouter()
return (
<button type="button" onClick={() => router.push('/dashboard')}>
Dashboard
</button>
)
}
Gut zu wissen:
- Für nicht-programmatische Navigation sollten Sie eine
<Link>
-Komponente verwenden.
Weitere Informationen finden Sie in der useRouter
-API-Referenz.
redirects
in next.config.js
Die redirects
-Option in der next.config.js
-Datei ermöglicht es, eingehende Anfragen basierend auf dem Pfad umzuleiten. Dies ist nützlich bei Änderungen der URL-Struktur oder bei bekannten Weiterleitungen.
redirects
unterstützt Pfad, Header-, Cookie- und Query-Matching für flexible Weiterleitungsregeln.
So verwenden Sie redirects
:
module.exports = {
async redirects() {
return [
// Einfache Weiterleitung
{
source: '/about',
destination: '/',
permanent: true,
},
// Wildcard-Pfad-Matching
{
source: '/blog/:slug',
destination: '/news/:slug',
permanent: true,
},
]
},
}
Weitere Informationen finden Sie in der redirects
-API-Referenz.
Gut zu wissen:
redirects
kann 307 (Temporary Redirect) oder 308 (Permanent Redirect) Statuscodes zurückgeben.- Auf einigen Plattformen gibt es Limits (z.B. 1.024 Weiterleitungen auf Vercel). Für große Mengen (1000+) sollten Sie Middleware verwenden. Siehe Weiterleitungen im großen Stil.
redirects
wird vor Middleware ausgeführt.
NextResponse.redirect
in Middleware
Middleware ermöglicht Code-Ausführung vor Abschluss einer Anfrage. Mit NextResponse.redirect
können Sie basierend auf der Anfrage umleiten, z.B. für Authentifizierung oder Session-Management.
Beispiel für Authentifizierungs-Weiterleitung:
import { NextResponse, NextRequest } from 'next/server'
import { authenticate } from 'auth-provider'
export function middleware(request: NextRequest) {
const isAuthenticated = authenticate(request)
if (isAuthenticated) {
return NextResponse.next()
}
return NextResponse.redirect(new URL('/login', request.url))
}
export const config = {
matcher: '/dashboard/:path*',
}
import { NextResponse } from 'next/server'
import { authenticate } from 'auth-provider'
export function middleware(request) {
const isAuthenticated = authenticate(request)
if (isAuthenticated) {
return NextResponse.next()
}
return NextResponse.redirect(new URL('/login', request.url))
}
export const config = {
matcher: '/dashboard/:path*',
}
Gut zu wissen:
- Middleware wird nach
redirects
innext.config.js
und vor dem Rendering ausgeführt.
Weitere Informationen finden Sie in der Middleware-Dokumentation.
Weiterleitungen im großen Stil (Fortgeschritten)
Für große Mengen an Weiterleitungen (1000+) können Sie eine benutzerdefinierte Middleware-Lösung erstellen, ohne die Anwendung neu zu deployen.
Dafür benötigen Sie:
- Eine Weiterleitungs-Map
- Optimierte Datenabfrage
Next.js-Beispiel: Siehe unser Middleware mit Bloom-Filter-Beispiel für eine Implementierung.
1. Erstellen und Speichern einer Weiterleitungs-Map
Eine Weiterleitungs-Map ist eine Liste von Weiterleitungen, die in einer Datenbank oder JSON-Datei gespeichert werden kann.
Beispiel-Datenstruktur:
{
"/old": {
"destination": "/new",
"permanent": true
},
"/blog/post-old": {
"destination": "/blog/post-new",
"permanent": true
}
}
In Middleware können Sie aus Datenbanken wie Vercels Edge Config oder Redis lesen:
import { NextResponse, NextRequest } from 'next/server'
import { get } from '@vercel/edge-config'
type RedirectEntry = {
destination: string
permanent: boolean
}
export async function middleware(request: NextRequest) {
const pathname = request.nextUrl.pathname
const redirectData = await get(pathname)
if (redirectData && typeof redirectData === 'string') {
const redirectEntry: RedirectEntry = JSON.parse(redirectData)
const statusCode = redirectEntry.permanent ? 308 : 307
return NextResponse.redirect(redirectEntry.destination, statusCode)
}
return NextResponse.next()
}
import { NextResponse } from 'next/server'
import { get } from '@vercel/edge-config'
export async function middleware(request) {
const pathname = request.nextUrl.pathname
const redirectData = await get(pathname)
if (redirectData) {
const redirectEntry = JSON.parse(redirectData)
const statusCode = redirectEntry.permanent ? 308 : 307
return NextResponse.redirect(redirectEntry.destination, statusCode)
}
return NextResponse.next()
}
2. Optimierung der Datenabfrageleistung
Das Lesen eines großen Datensatzes für jede eingehende Anfrage kann langsam und ressourcenintensiv sein. Es gibt zwei Möglichkeiten, die Leistung bei der Datenabfrage zu optimieren:
- Verwenden Sie eine Datenbank, die für schnelle Lesevorgänge optimiert ist, wie z.B. Vercel Edge Config oder Redis.
- Verwenden Sie eine Datenabfragestrategie wie einen Bloom-Filter, um effizient zu prüfen, ob eine Weiterleitung existiert, bevor die größere Weiterleitungsdatei oder Datenbank gelesen wird.
Bezogen auf das vorherige Beispiel können Sie eine generierte Bloom-Filter-Datei in die Middleware importieren und dann prüfen, ob der Pfad der eingehenden Anfrage im Bloom-Filter enthalten ist.
Falls ja, leiten Sie die Anfrage an einen Route Handler weiter, der die eigentliche Datei überprüft und den Benutzer zur entsprechenden URL weiterleitet. Dadurch wird vermieden, eine große Weiterleitungsdatei in die Middleware zu importieren, was jede eingehende Anfrage verlangsamen könnte.
import { NextResponse, NextRequest } from 'next/server'
import { ScalableBloomFilter } from 'bloom-filters'
import GeneratedBloomFilter from './redirects/bloom-filter.json'
type RedirectEntry = {
destination: string
permanent: boolean
}
// Initialisiere Bloom-Filter aus einer generierten JSON-Datei
const bloomFilter = ScalableBloomFilter.fromJSON(GeneratedBloomFilter as any)
export async function middleware(request: NextRequest) {
// Hole den Pfad der eingehenden Anfrage
const pathname = request.nextUrl.pathname
// Prüfe, ob der Pfad im Bloom-Filter enthalten ist
if (bloomFilter.has(pathname)) {
// Leite den Pfad an den Route Handler weiter
const api = new URL(
`/api/redirects?pathname=${encodeURIComponent(request.nextUrl.pathname)}`,
request.nextUrl.origin
)
try {
// Hole Weiterleitungsdaten vom Route Handler
const redirectData = await fetch(api)
if (redirectData.ok) {
const redirectEntry: RedirectEntry | undefined =
await redirectData.json()
if (redirectEntry) {
// Bestimme den Statuscode
const statusCode = redirectEntry.permanent ? 308 : 307
// Leite zur Ziel-URL weiter
return NextResponse.redirect(redirectEntry.destination, statusCode)
}
}
} catch (error) {
console.error(error)
}
}
// Keine Weiterleitung gefunden, Anfrage ohne Weiterleitung fortsetzen
return NextResponse.next()
}
import { NextResponse } from 'next/server'
import { ScalableBloomFilter } from 'bloom-filters'
import GeneratedBloomFilter from './redirects/bloom-filter.json'
// Initialisiere Bloom-Filter aus einer generierten JSON-Datei
const bloomFilter = ScalableBloomFilter.fromJSON(GeneratedBloomFilter)
export async function middleware(request) {
// Hole den Pfad der eingehenden Anfrage
const pathname = request.nextUrl.pathname
// Prüfe, ob der Pfad im Bloom-Filter enthalten ist
if (bloomFilter.has(pathname)) {
// Leite den Pfad an den Route Handler weiter
const api = new URL(
`/api/redirects?pathname=${encodeURIComponent(request.nextUrl.pathname)}`,
request.nextUrl.origin
)
try {
// Hole Weiterleitungsdaten vom Route Handler
const redirectData = await fetch(api)
if (redirectData.ok) {
const redirectEntry = await redirectData.json()
if (redirectEntry) {
// Bestimme den Statuscode
const statusCode = redirectEntry.permanent ? 308 : 307
// Leite zur Ziel-URL weiter
return NextResponse.redirect(redirectEntry.destination, statusCode)
}
}
} catch (error) {
console.error(error)
}
}
// Keine Weiterleitung gefunden, Anfrage ohne Weiterleitung fortsetzen
return NextResponse.next()
}
Dann im Route Handler:
import { NextRequest, NextResponse } from 'next/server'
import redirects from '@/app/redirects/redirects.json'
type RedirectEntry = {
destination: string
permanent: boolean
}
export function GET(request: NextRequest) {
const pathname = request.nextUrl.searchParams.get('pathname')
if (!pathname) {
return new Response('Bad Request', { status: 400 })
}
// Hole den Weiterleitungseintrag aus der redirects.json-Datei
const redirect = (redirects as Record<string, RedirectEntry>)[pathname]
// Berücksichtige falsch positive Ergebnisse des Bloom-Filters
if (!redirect) {
return new Response('No redirect', { status: 400 })
}
// Gib den Weiterleitungseintrag zurück
return NextResponse.json(redirect)
}
import { NextResponse } from 'next/server'
import redirects from '@/app/redirects/redirects.json'
export function GET(request) {
const pathname = request.nextUrl.searchParams.get('pathname')
if (!pathname) {
return new Response('Bad Request', { status: 400 })
}
// Hole den Weiterleitungseintrag aus der redirects.json-Datei
const redirect = redirects[pathname]
// Berücksichtige falsch positive Ergebnisse des Bloom-Filters
if (!redirect) {
return new Response('No redirect', { status: 400 })
}
// Gib den Weiterleitungseintrag zurück
return NextResponse.json(redirect)
}
Gut zu wissen:
- Um einen Bloom-Filter zu generieren, können Sie eine Bibliothek wie
bloom-filters
verwenden.- Sie sollten Anfragen an Ihren Route Handler validieren, um bösartige Anfragen zu verhindern.