diff --git a/packages/next/next-server/lib/router/utils/resolve-rewrites.ts b/packages/next/next-server/lib/router/utils/resolve-rewrites.ts
index c2bef108c98d1..b6551862abffc 100644
--- a/packages/next/next-server/lib/router/utils/resolve-rewrites.ts
+++ b/packages/next/next-server/lib/router/utils/resolve-rewrites.ts
@@ -101,19 +101,16 @@ export default function resolveRewrites(
let finished = false
for (let i = 0; i < rewrites.beforeFiles.length; i++) {
- const rewrite = rewrites.beforeFiles[i]
-
- if (handleRewrite(rewrite)) {
- finished = true
- break
- }
+ // we don't end after match in beforeFiles to allow
+ // continuing through all beforeFiles rewrites
+ handleRewrite(rewrites.beforeFiles[i])
}
+ matchedPage = pages.includes(fsPathname)
- if (!pages.includes(fsPathname)) {
+ if (!matchedPage) {
if (!finished) {
for (let i = 0; i < rewrites.afterFiles.length; i++) {
- const rewrite = rewrites.afterFiles[i]
- if (handleRewrite(rewrite)) {
+ if (handleRewrite(rewrites.afterFiles[i])) {
finished = true
break
}
@@ -129,8 +126,7 @@ export default function resolveRewrites(
if (!finished) {
for (let i = 0; i < rewrites.fallback.length; i++) {
- const rewrite = rewrites.fallback[i]
- if (handleRewrite(rewrite)) {
+ if (handleRewrite(rewrites.fallback[i])) {
finished = true
break
}
diff --git a/packages/next/next-server/server/next-server.ts b/packages/next/next-server/server/next-server.ts
index d9fb26c72d8bb..d1f38c8ae60e8 100644
--- a/packages/next/next-server/server/next-server.ts
+++ b/packages/next/next-server/server/next-server.ts
@@ -902,11 +902,11 @@ export default class Server {
} as Route
})
- const buildRewrite = (rewrite: Rewrite) => {
+ const buildRewrite = (rewrite: Rewrite, check = true) => {
const rewriteRoute = getCustomRoute(rewrite, 'rewrite')
return {
...rewriteRoute,
- check: true,
+ check,
type: rewriteRoute.type,
name: `Rewrite route ${rewriteRoute.source}`,
match: rewriteRoute.match,
@@ -975,11 +975,17 @@ export default class Server {
if (!this.minimalMode) {
if (Array.isArray(this.customRoutes.rewrites)) {
- afterFiles = this.customRoutes.rewrites.map(buildRewrite)
+ afterFiles = this.customRoutes.rewrites.map((r) => buildRewrite(r))
} else {
- beforeFiles = this.customRoutes.rewrites.beforeFiles.map(buildRewrite)
- afterFiles = this.customRoutes.rewrites.afterFiles.map(buildRewrite)
- fallback = this.customRoutes.rewrites.fallback.map(buildRewrite)
+ beforeFiles = this.customRoutes.rewrites.beforeFiles.map((r) =>
+ buildRewrite(r, false)
+ )
+ afterFiles = this.customRoutes.rewrites.afterFiles.map((r) =>
+ buildRewrite(r)
+ )
+ fallback = this.customRoutes.rewrites.fallback.map((r) =>
+ buildRewrite(r)
+ )
}
}
diff --git a/test/integration/custom-routes/next.config.js b/test/integration/custom-routes/next.config.js
index 8ff2e9b06411b..f22c4c3bac9ce 100644
--- a/test/integration/custom-routes/next.config.js
+++ b/test/integration/custom-routes/next.config.js
@@ -190,6 +190,10 @@ module.exports = {
],
destination: '/with-params?idk=:idk',
},
+ {
+ source: '/blog/about',
+ destination: '/hello',
+ },
],
beforeFiles: [
{
@@ -202,6 +206,10 @@ module.exports = {
],
destination: '/with-params?overridden=1',
},
+ {
+ source: '/old-blog/:path*',
+ destination: '/blog/:path*',
+ },
],
}
},
diff --git a/test/integration/custom-routes/pages/nav.js b/test/integration/custom-routes/pages/nav.js
index 626f7e0d9f8aa..88ca61b02404c 100644
--- a/test/integration/custom-routes/pages/nav.js
+++ b/test/integration/custom-routes/pages/nav.js
@@ -32,5 +32,13 @@ export default () => (
to rewritten dynamic
+
+ to /hello?overrideMe=1
+
+
+
+ to /old-blog/post-1
+
+
>
)
diff --git a/test/integration/custom-routes/test/index.test.js b/test/integration/custom-routes/test/index.test.js
index bbfb1a054c9d5..461774b7a799a 100644
--- a/test/integration/custom-routes/test/index.test.js
+++ b/test/integration/custom-routes/test/index.test.js
@@ -38,6 +38,25 @@ let appPort
let app
const runTests = (isDev = false) => {
+ it('should continue in beforeFiles rewrites', async () => {
+ const res = await fetchViaHTTP(appPort, '/old-blog/about')
+ expect(res.status).toBe(200)
+
+ const html = await res.text()
+ const $ = cheerio.load(html)
+
+ expect($('#hello').text()).toContain('Hello')
+
+ const browser = await webdriver(appPort, '/nav')
+
+ await browser.eval('window.beforeNav = 1')
+ await browser
+ .elementByCss('#to-old-blog')
+ .click()
+ .waitForElementByCss('#hello')
+ expect(await browser.elementByCss('#hello').text()).toContain('Hello')
+ })
+
it('should not hang when proxy rewrite fails', async () => {
const res = await fetchViaHTTP(appPort, '/to-nowhere', undefined, {
timeout: 5000,
@@ -781,6 +800,20 @@ const runTests = (isDev = false) => {
overrideMe: '1',
overridden: '1',
})
+
+ const browser = await webdriver(appPort, '/nav')
+ await browser.eval('window.beforeNav = 1')
+ await browser.elementByCss('#to-overridden').click()
+ await browser.waitForElementByCss('#query')
+
+ expect(await browser.eval('window.next.router.pathname')).toBe(
+ '/with-params'
+ )
+ expect(JSON.parse(await browser.elementByCss('#query').text())).toEqual({
+ overridden: '1',
+ overrideMe: '1',
+ })
+ expect(await browser.eval('window.beforeNav')).toBe(1)
})
it('should match has header redirect correctly', async () => {
@@ -1401,6 +1434,13 @@ const runTests = (isDev = false) => {
regex: normalizeRegEx('^\\/hello$'),
source: '/hello',
},
+ {
+ destination: '/blog/:path*',
+ regex: normalizeRegEx(
+ '^\\/old-blog(?:\\/((?:[^\\/]+?)(?:\\/(?:[^\\/]+?))*))?$'
+ ),
+ source: '/old-blog/:path*',
+ },
],
afterFiles: [
{
@@ -1630,6 +1670,11 @@ const runTests = (isDev = false) => {
regex: normalizeRegEx('^\\/has-rewrite-7$'),
source: '/has-rewrite-7',
},
+ {
+ destination: '/hello',
+ regex: normalizeRegEx('^\\/blog\\/about$'),
+ source: '/blog/about',
+ },
],
fallback: [],
},