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:falseoderundefined- wenn false, wird der basePath beim Abgleich nicht berücksichtigt, kann nur für externe Rewrites verwendet werden.locale:falseoderundefined- ob die Locale beim Abgleich nicht berücksichtigt werden soll.hasist ein Array von has-Objekten mit den Eigenschaftentype,keyundvalue.missingist ein Array von missing-Objekten mit den Eigenschaftentype,keyundvalue.
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' ingetStaticPathsverwenden, werden die in Ihrernext.config.jsdefiniertenfallback-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,hostoderquerysein.key:String- der Schlüssel des ausgewählten Typs, gegen den abgeglichen werden soll.value:Stringoderundefined- 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-secondverwendet wird, dann kannsecondin der Destination mit:paramNameverwendet 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. |