Rewrites
Rewrites ermöglichen es Ihnen, einen eingehenden Anfragepfad einem anderen Zielpfad zuzuordnen.
Rewrites fungieren als URL-Proxy und maskieren den Zielpfad, sodass es für den Benutzer so aussieht, als hätte er seinen Standort auf der Website nicht geändert. Im Gegensatz dazu leiten Redirects zu einer neuen Seite weiter und zeigen die URL-Änderungen an.
Um Rewrites zu verwenden, können Sie den rewrites
-Schlüssel in next.config.js
nutzen:
module.exports = {
async rewrites() {
return [
{
source: '/about',
destination: '/',
},
]
},
}
Rewrites werden auf das clientseitige Routing angewendet, ein <Link href="/about">
würde in obigem Beispiel den Rewrite erhalten.
rewrites
ist eine asynchrone Funktion, die entweder ein Array oder ein Objekt von Arrays zurückerwartet (siehe unten), das Objekte mit den Eigenschaften source
und destination
enthält:
source
:String
- ist das Muster des eingehenden Anfragepfads.destination
:String
- ist der Pfad, zu dem geroutet werden soll.basePath
:false
oderundefined
- wenn false, wird der basePath beim Abgleich nicht berücksichtigt, kann nur für externe Rewrites verwendet werden.locale
:false
oderundefined
- ob die Locale beim Abgleich nicht berücksichtigt werden soll.has
ist ein Array von has-Objekten mit den Eigenschaftentype
,key
undvalue
.missing
ist ein Array von missing-Objekten mit den Eigenschaftentype
,key
undvalue
.
Wenn die rewrites
-Funktion ein Array zurückgibt, werden Rewrites nach der Überprüfung des Dateisystems (Seiten und /public
-Dateien) und vor dynamischen Routen angewendet. Wenn die rewrites
-Funktion ein Objekt von Arrays mit einer bestimmten Struktur zurückgibt, kann dieses Verhalten ab v10.1
von Next.js geändert und feiner kontrolliert werden:
module.exports = {
async rewrites() {
return {
beforeFiles: [
// Diese Rewrites werden nach Headers/Redirects
// und vor allen Dateien inklusive _next/public-Dateien überprüft,
// was das Überschreiben von Seiten-Dateien ermöglicht
{
source: '/some-page',
destination: '/somewhere-else',
has: [{ type: 'query', key: 'overrideMe' }],
},
],
afterFiles: [
// Diese Rewrites werden nach Seiten/public-Dateien
// überprüft, aber vor dynamischen Routen
{
source: '/non-existent',
destination: '/somewhere-else',
},
],
fallback: [
// Diese Rewrites werden sowohl nach Seiten/public-Dateien
// als auch nach dynamischen Routen überprüft
{
source: '/:path*',
destination: `https://my-old-site.com/:path*`,
},
],
}
},
}
Gut zu wissen: Rewrites in
beforeFiles
überprüfen das Dateisystem/dynamische Routen nicht unmittelbar nach dem Abgleich einer Source, sie werden fortgesetzt, bis allebeforeFiles
überprüft wurden.
Die Reihenfolge, in der Next.js Routen überprüft werden, ist:
- Headers werden überprüft/angewendet
- Redirects werden überprüft/angewendet
beforeFiles
-Rewrites werden überprüft/angewendet- Statische Dateien aus dem public-Verzeichnis,
_next/static
-Dateien und nicht-dynamische Seiten werden überprüft/bereitgestellt afterFiles
-Rewrites werden überprüft/angewendet. Wenn einer dieser Rewrites übereinstimmt, werden dynamische Routen/statische Dateien nach jedem Abgleich überprüftfallback
-Rewrites werden überprüft/angewendet. Diese werden vor dem Rendern der 404-Seite und nach der Überprüfung dynamischer Routen/aller statischen Assets angewendet. Wenn Sie fallback: true/'blocking' ingetStaticPaths
verwenden, werden die in Ihrernext.config.js
definiertenfallback
-Rewrites nicht ausgeführt.
Rewrite-Parameter
Wenn Parameter in einem Rewrite verwendet werden, werden die Parameter standardmäßig in der Query übergeben, wenn keiner der Parameter in der destination
verwendet wird.
module.exports = {
async rewrites() {
return [
{
source: '/old-about/:path*',
destination: '/about', // Der :path-Parameter wird hier nicht verwendet und wird automatisch in der Query übergeben
},
]
},
}
Wenn ein Parameter in der Destination verwendet wird, werden keine Parameter automatisch in der Query übergeben.
module.exports = {
async rewrites() {
return [
{
source: '/docs/:path*',
destination: '/:path*', // Der :path-Parameter wird hier verwendet und wird nicht automatisch in der Query übergeben
},
]
},
}
Sie können die Parameter dennoch manuell in der Query übergeben, wenn einer bereits in der Destination verwendet wird, indem Sie die Query in der destination
angeben.
module.exports = {
async rewrites() {
return [
{
source: '/:first/:second',
destination: '/:first?second=:second',
// Da der :first-Parameter in der Destination verwendet wird, wird der :second-Parameter
// nicht automatisch in der Query hinzugefügt, obwohl wir ihn manuell hinzufügen können,
// wie oben gezeigt
},
]
},
}
Gut zu wissen: Statische Seiten aus Automatic Static Optimization oder Prerendering werden die Parameter aus Rewrites nach der Hydration auf dem Client geparst und in der Query bereitgestellt.
Pfadabgleich
Pfadabgleiche sind erlaubt, zum Beispiel wird /blog/:slug
mit /blog/hello-world
übereinstimmen (keine verschachtelten Pfade):
module.exports = {
async rewrites() {
return [
{
source: '/blog/:slug',
destination: '/news/:slug', // Übereinstimmende Parameter können in der Destination verwendet werden
},
]
},
}
Wildcard-Pfadabgleich
Um einen Wildcard-Pfad abzugleichen, können Sie *
nach einem Parameter verwenden, zum Beispiel wird /blog/:slug*
mit /blog/a/b/c/d/hello-world
übereinstimmen:
module.exports = {
async rewrites() {
return [
{
source: '/blog/:slug*',
destination: '/news/:slug*', // Übereinstimmende Parameter können in der Destination verwendet werden
},
]
},
}
Regex-Pfadabgleich
Um einen Regex-Pfad abzugleichen, können Sie den Regex in Klammern nach einem Parameter einschließen, zum Beispiel wird /blog/:slug(\\d{1,})
mit /blog/123
übereinstimmen, aber nicht mit /blog/abc
:
module.exports = {
async rewrites() {
return [
{
source: '/old-blog/:post(\\d{1,})',
destination: '/blog/:post', // Übereinstimmende Parameter können in der Destination verwendet werden
},
]
},
}
Die folgenden Zeichen (
, )
, {
, }
, :
, *
, +
, ?
werden für Regex-Pfadabgleiche verwendet. Wenn sie in der source
als nicht-spezielle Werte verwendet werden, müssen sie durch Hinzufügen von \\
davor escaped werden:
module.exports = {
async rewrites() {
return [
{
// Dies wird mit `/english(default)/something` übereinstimmen
source: '/english\\(default\\)/:slug',
destination: '/en-us/:slug',
},
]
},
}
Header-, Cookie- und Query-Abgleich
Um einen Rewrite nur dann anzuwenden, wenn Header-, Cookie- oder Query-Werte ebenfalls übereinstimmen, kann das Feld has
verwendet werden, oder das Feld missing
, um Abgleiche auszuschließen. Sowohl die source
als auch alle has
-Elemente müssen übereinstimmen und alle missing
-Elemente dürfen nicht übereinstimmen, damit der Rewrite angewendet wird.
has
- und missing
-Elemente können die folgenden Felder haben:
type
:String
- muss entwederheader
,cookie
,host
oderquery
sein.key
:String
- der Schlüssel des ausgewählten Typs, gegen den abgeglichen werden soll.value
:String
oderundefined
- der zu überprüfende Wert. Wenn undefined, wird jeder Wert übereinstimmen. Ein regex-ähnlicher String kann verwendet werden, um einen bestimmten Teil des Werts zu erfassen, z.B. wenn der Wertfirst-(?<paramName>.*)
fürfirst-second
verwendet wird, dann kannsecond
in der Destination mit:paramName
verwendet werden.
module.exports = {
async rewrites() {
return [
// Wenn der Header `x-rewrite-me` vorhanden ist,
// wird dieser Rewrite angewendet
{
source: '/:path*',
has: [
{
type: 'header',
key: 'x-rewrite-me',
},
],
destination: '/another-page',
},
// Wenn der Header `x-rewrite-me` nicht vorhanden ist,
// wird dieser Rewrite angewendet
{
source: '/:path*',
missing: [
{
type: 'header',
key: 'x-rewrite-me',
},
],
destination: '/another-page',
},
// Wenn die Source, Query und Cookie übereinstimmen,
// wird dieser Rewrite angewendet
{
source: '/specific/:path*',
has: [
{
type: 'query',
key: 'page',
// Der Seitenwert wird in der Destination nicht verfügbar sein,
// da der Wert bereitgestellt wird und keine benannte Erfassungsgruppe
// verwendet wird, z.B. (?<page>home)
value: 'home',
},
{
type: 'cookie',
key: 'authorized',
value: 'true',
},
],
destination: '/:path*/home',
},
// Wenn der Header `x-authorized` vorhanden ist und
// einen übereinstimmenden Wert enthält, wird dieser Rewrite angewendet
{
source: '/:path*',
has: [
{
type: 'header',
key: 'x-authorized',
value: '(?<authorized>yes|true)',
},
],
destination: '/home?authorized=:authorized',
},
// Wenn der Host `example.com` ist,
// wird dieser Rewrite angewendet
{
source: '/:path*',
has: [
{
type: 'host',
value: 'example.com',
},
],
destination: '/another-page',
},
]
},
}
Rewriting zu einer externen URL
Rewrites ermöglichen es Ihnen, zu einer externen URL umzuleiten. Dies ist besonders nützlich für die schrittweise Einführung von Next.js. Das folgende Beispiel zeigt einen Rewrite, der die /blog
-Route Ihrer Hauptanwendung zu einer externen Site umleitet.
module.exports = {
async rewrites() {
return [
{
source: '/blog',
destination: 'https://example.com/blog',
},
{
source: '/blog/:slug',
destination: 'https://example.com/blog/:slug', // Übereinstimmende Parameter können in der Destination verwendet werden
},
]
},
}
Wenn Sie trailingSlash: true
verwenden, müssen Sie auch einen Schrägstrich im source
-Parameter einfügen. Wenn der Zielserver ebenfalls einen Schrägstrich erwartet, sollte dieser auch im destination
-Parameter enthalten sein.
module.exports = {
trailingSlash: true,
async rewrites() {
return [
{
source: '/blog/',
destination: 'https://example.com/blog/',
},
{
source: '/blog/:path*/',
destination: 'https://example.com/blog/:path*/',
},
]
},
}
Inkrementelle Einführung von Next.js
Sie können Next.js auch so konfigurieren, dass es nach der Überprüfung aller Next.js-Routen auf das Proxying zu einer bestehenden Website zurückfällt.
Auf diese Weise müssen Sie die Rewrites-Konfiguration nicht ändern, wenn Sie weitere Seiten zu Next.js migrieren.
module.exports = {
async rewrites() {
return {
fallback: [
{
source: '/:path*',
destination: `https://custom-routes-proxying-endpoint.vercel.app/:path*`,
},
],
}
},
}
Rewrites mit basePath-Unterstützung
Wenn Sie basePath
-Unterstützung mit Rewrites verwenden, wird jede source
und destination
automatisch mit dem basePath
präfixiert, es sei denn, Sie fügen basePath: false
zum Rewrite hinzu:
module.exports = {
basePath: '/docs',
async rewrites() {
return [
{
source: '/with-basePath', // wird automatisch zu /docs/with-basePath
destination: '/another', // wird automatisch zu /docs/another
},
{
// fügt /docs nicht zu /without-basePath hinzu, da basePath: false gesetzt ist
// Hinweis: Dies kann nicht für interne Rewrites verwendet werden, z.B. `destination: '/another'`
source: '/without-basePath',
destination: 'https://example.com',
basePath: false,
},
]
},
}
Rewrites mit i18n-Unterstützung
Wenn Sie i18n
-Unterstützung mit Rewrites verwenden, wird jede source
und destination
automatisch präfixiert, um die konfigurierten locales
zu handhaben, es sei denn, Sie fügen locale: false
zum Rewrite hinzu. Wenn locale: false
verwendet wird, müssen Sie source
und destination
mit einer Locale präfixieren, damit sie korrekt abgeglichen werden können.
module.exports = {
i18n: {
locales: ['en', 'fr', 'de'],
defaultLocale: 'en',
},
async rewrites() {
return [
{
source: '/with-locale', // handhabt automatisch alle Locales
destination: '/another', // übergibt automatisch die Locale
},
{
// handhabt Locales nicht automatisch, da locale: false gesetzt ist
source: '/nl/with-locale-manual',
destination: '/nl/another',
locale: false,
},
{
// stimmt mit '/' überein, da `en` die defaultLocale ist
source: '/en',
destination: '/en/another',
locale: false,
},
{
// es ist möglich, alle Locales abzugleichen, auch wenn locale: false gesetzt ist
source: '/:locale/api-alias/:path*',
destination: '/api/:path*',
locale: false,
},
{
// wird in /(en|fr|de)/(.*) umgewandelt, sodass es nicht mit den Top-Level
// `/` oder `/fr`-Routen übereinstimmt, wie es /:path* tun würde
source: '/(.*)',
destination: '/another',
},
]
},
}
Versionsverlauf
Version | Änderungen |
---|---|
v13.3.0 | missing hinzugefügt. |
v10.2.0 | has hinzugefügt. |
v9.5.0 | Header-Unterstützung hinzugefügt. |