diff --git a/packages/next/shared/lib/router/utils/resolve-rewrites.ts b/packages/next/shared/lib/router/utils/resolve-rewrites.ts
index 30fe1a35a4f56a8..c69bac0091a2d8e 100644
--- a/packages/next/shared/lib/router/utils/resolve-rewrites.ts
+++ b/packages/next/shared/lib/router/utils/resolve-rewrites.ts
@@ -106,7 +106,7 @@ export default function resolveRewrites(
for (let i = 0; i < rewrites.beforeFiles.length; i++) {
// we don't end after match in beforeFiles to allow
// continuing through all beforeFiles rewrites
- finished = handleRewrite(rewrites.beforeFiles[i]) || false
+ handleRewrite(rewrites.beforeFiles[i])
}
matchedPage = pages.includes(fsPathname)
diff --git a/test/integration/custom-routes/next.config.js b/test/integration/custom-routes/next.config.js
index 7780bda50eebdff..70814483c17eb92 100644
--- a/test/integration/custom-routes/next.config.js
+++ b/test/integration/custom-routes/next.config.js
@@ -224,6 +224,10 @@ module.exports = {
source: '/overridden',
destination: 'https://vercel.com',
},
+ {
+ source: '/nfl/:path*',
+ destination: '/_sport/nfl/:path*',
+ },
],
}
},
diff --git a/test/integration/custom-routes/pages/_sport/[slug]/index.js b/test/integration/custom-routes/pages/_sport/[slug]/index.js
new file mode 100644
index 000000000000000..5c0e0dfbda5d2c4
--- /dev/null
+++ b/test/integration/custom-routes/pages/_sport/[slug]/index.js
@@ -0,0 +1,13 @@
+import { useRouter } from 'next/router'
+
+export default function Page() {
+ const router = useRouter()
+ return (
+ <>
+
/_sport/[slug]
+ {JSON.stringify(router.query)}
+ {router.asPath}
+ {router.pathname}
+ >
+ )
+}
diff --git a/test/integration/custom-routes/pages/_sport/[slug]/test.js b/test/integration/custom-routes/pages/_sport/[slug]/test.js
new file mode 100644
index 000000000000000..ccbe746692eed75
--- /dev/null
+++ b/test/integration/custom-routes/pages/_sport/[slug]/test.js
@@ -0,0 +1,13 @@
+import { useRouter } from 'next/router'
+
+export default function Page() {
+ const router = useRouter()
+ return (
+ <>
+ /_sport/[slug]/test
+ {JSON.stringify(router.query)}
+ {router.asPath}
+ {router.pathname}
+ >
+ )
+}
diff --git a/test/integration/custom-routes/pages/nav.js b/test/integration/custom-routes/pages/nav.js
index 1b6663537c4b173..e2acbb4d22fde30 100644
--- a/test/integration/custom-routes/pages/nav.js
+++ b/test/integration/custom-routes/pages/nav.js
@@ -44,6 +44,15 @@ const Page = () => (
to /overridden
+
+ to /nfl
+
+
+
+ to /nfl/test
+
+
>
)
+
export default Page
diff --git a/test/integration/custom-routes/test/index.test.js b/test/integration/custom-routes/test/index.test.js
index 404d5f7f977dac8..ae28cee1f73186f 100644
--- a/test/integration/custom-routes/test/index.test.js
+++ b/test/integration/custom-routes/test/index.test.js
@@ -99,6 +99,58 @@ const runTests = (isDev = false) => {
)
})
+ it('should handle beforeFiles rewrite to dynamic route correctly', async () => {
+ const res = await fetchViaHTTP(appPort, '/nfl')
+ const html = await res.text()
+
+ if (res.status !== 200) {
+ console.error('Invalid response', html)
+ }
+ expect(res.status).toBe(200)
+ expect(html).toContain('/_sport/[slug]')
+
+ const browser = await webdriver(appPort, '/nav')
+ await browser.eval('window.beforeNav = 1')
+ await browser.elementByCss('#to-before-files-dynamic').click()
+ await check(
+ () => browser.eval('document.documentElement.innerHTML'),
+ /_sport\/\[slug\]/
+ )
+ expect(JSON.parse(await browser.elementByCss('#query').text())).toEqual({
+ slug: 'nfl',
+ })
+ expect(await browser.elementByCss('#pathname').text()).toBe(
+ '/_sport/[slug]'
+ )
+ expect(await browser.eval('window.beforeNav')).toBe(1)
+ })
+
+ it('should handle beforeFiles rewrite to partly dynamic route correctly', async () => {
+ const res = await fetchViaHTTP(appPort, '/nfl')
+ const html = await res.text()
+
+ if (res.status !== 200) {
+ console.error('Invalid response', html)
+ }
+ expect(res.status).toBe(200)
+ expect(html).toContain('/_sport/[slug]')
+
+ const browser = await webdriver(appPort, '/nav')
+ await browser.eval('window.beforeNav = 1')
+ await browser.elementByCss('#to-before-files-dynamic-again').click()
+ await check(
+ () => browser.eval('document.documentElement.innerHTML'),
+ /_sport\/\[slug\]\/test/
+ )
+ expect(JSON.parse(await browser.elementByCss('#query').text())).toEqual({
+ slug: 'nfl',
+ })
+ expect(await browser.elementByCss('#pathname').text()).toBe(
+ '/_sport/[slug]/test'
+ )
+ expect(await browser.eval('window.beforeNav')).toBe(1)
+ })
+
it('should support long URLs for rewrites', async () => {
const res = await fetchViaHTTP(
appPort,
@@ -1720,6 +1772,13 @@ const runTests = (isDev = false) => {
regex: normalizeRegEx('^\\/overridden(?:\\/)?$'),
source: '/overridden',
},
+ {
+ destination: '/_sport/nfl/:path*',
+ regex: normalizeRegEx(
+ '^\\/nfl(?:\\/((?:[^\\/]+?)(?:\\/(?:[^\\/]+?))*))?(?:\\/)?$'
+ ),
+ source: '/nfl/:path*',
+ },
],
afterFiles: [
{
@@ -1973,6 +2032,22 @@ const runTests = (isDev = false) => {
fallback: [],
},
dynamicRoutes: [
+ {
+ namedRegex: '^/_sport/(?[^/]+?)(?:/)?$',
+ page: '/_sport/[slug]',
+ regex: normalizeRegEx('^\\/_sport\\/([^\\/]+?)(?:\\/)?$'),
+ routeKeys: {
+ slug: 'slug',
+ },
+ },
+ {
+ namedRegex: '^/_sport/(?[^/]+?)/test(?:/)?$',
+ page: '/_sport/[slug]/test',
+ regex: normalizeRegEx('^\\/_sport\\/([^\\/]+?)\\/test(?:\\/)?$'),
+ routeKeys: {
+ slug: 'slug',
+ },
+ },
{
namedRegex: '^/another/(?[^/]+?)(?:/)?$',
page: '/another/[id]',