diff --git a/demos/middleware/pages/index.js b/demos/middleware/pages/index.js
index 775f996a1e..b229d2bafd 100644
--- a/demos/middleware/pages/index.js
+++ b/demos/middleware/pages/index.js
@@ -16,7 +16,9 @@ export default function Home() {
Welcome to Next.js!
-
Rewrite me
+ Rewrite URL
+ Rewrite to absolute URL
+ Rewrite to external URL
)
diff --git a/demos/middleware/pages/shows/rewrite-absolute/_middleware.ts b/demos/middleware/pages/shows/rewrite-absolute/_middleware.ts
new file mode 100644
index 0000000000..6c7696a767
--- /dev/null
+++ b/demos/middleware/pages/shows/rewrite-absolute/_middleware.ts
@@ -0,0 +1,8 @@
+import { NextResponse } from 'next/server'
+import { NextFetchEvent, NextRequest } from 'next/server'
+
+export function middleware(req: NextRequest, ev: NextFetchEvent) {
+ const res = NextResponse.rewrite(new URL('/shows/100', req.url))
+ res.headers.set('x-modified-in-rewrite', 'true')
+ return res
+}
diff --git a/demos/middleware/pages/shows/rewrite-absolute/index.js b/demos/middleware/pages/shows/rewrite-absolute/index.js
new file mode 100644
index 0000000000..871c824075
--- /dev/null
+++ b/demos/middleware/pages/shows/rewrite-absolute/index.js
@@ -0,0 +1,9 @@
+const Show = () => {
+ return (
+
+
This should have been rewritten
+
+ )
+}
+
+export default Show
diff --git a/demos/middleware/pages/shows/rewrite-external/_middleware.ts b/demos/middleware/pages/shows/rewrite-external/_middleware.ts
new file mode 100644
index 0000000000..1fdaeb8ec9
--- /dev/null
+++ b/demos/middleware/pages/shows/rewrite-external/_middleware.ts
@@ -0,0 +1,8 @@
+import { NextResponse } from 'next/server'
+import { NextFetchEvent, NextRequest } from 'next/server'
+
+export function middleware(req: NextRequest, ev: NextFetchEvent) {
+ const res = NextResponse.rewrite('http://example.com/')
+ res.headers.set('x-modified-in-rewrite', 'true')
+ return res
+}
diff --git a/demos/middleware/pages/shows/rewrite-external/index.js b/demos/middleware/pages/shows/rewrite-external/index.js
new file mode 100644
index 0000000000..871c824075
--- /dev/null
+++ b/demos/middleware/pages/shows/rewrite-external/index.js
@@ -0,0 +1,9 @@
+const Show = () => {
+ return (
+
+
This should have been rewritten
+
+ )
+}
+
+export default Show
diff --git a/plugin/src/templates/edge/utils.ts b/plugin/src/templates/edge/utils.ts
index e780e7684d..57230273f5 100644
--- a/plugin/src/templates/edge/utils.ts
+++ b/plugin/src/templates/edge/utils.ts
@@ -5,6 +5,19 @@ export interface FetchEventResult {
waitUntil: Promise
}
+/**
+ * This is how Next handles rewritten URLs.
+ */
+ export function relativizeURL(url: string | string, base: string | URL) {
+ const baseURL = typeof base === 'string' ? new URL(base) : base
+ const relative = new URL(url, base)
+ const origin = `${baseURL.protocol}//${baseURL.host}`
+ return `${relative.protocol}//${relative.host}` === origin
+ ? relative.toString().replace(origin, '')
+ : relative.toString()
+}
+
+
export const addMiddlewareHeaders = async (
originResponse: Promise | Response,
middlewareResponse: Response,
@@ -14,7 +27,8 @@ export const addMiddlewareHeaders = async (
return originResponse
}
// We need to await the response to get the origin headers, then we can add the ones from middleware.
- const response = await originResponse
+ const res = await originResponse
+ const response = new Response(res.body, res)
middlewareResponse.headers.forEach((value, key) => {
response.headers.set(key, value)
})
@@ -33,6 +47,14 @@ export const buildResponse = async ({
request.headers.set('x-nf-next-middleware', 'skip')
const rewrite = res.headers.get('x-middleware-rewrite')
if (rewrite) {
+ const rewriteUrl = new URL(rewrite, request.url)
+ const baseUrl = new URL(request.url)
+ if(rewriteUrl.hostname !== baseUrl.hostname) {
+ // Netlify Edge Functions don't support proxying to external domains, but Next middleware does
+ const proxied = fetch(new Request(rewriteUrl.toString(), request))
+ return addMiddlewareHeaders(proxied, res)
+ }
+ res.headers.set('x-middleware-rewrite', relativizeURL(rewrite, request.url))
return addMiddlewareHeaders(context.rewrite(rewrite), res)
}
if (res.headers.get('x-middleware-next') === '1') {