diff --git a/packages/next/src/shared/lib/router/router.ts b/packages/next/src/shared/lib/router/router.ts index 3aa2d9e3d2c5c..a17eac086963e 100644 --- a/packages/next/src/shared/lib/router/router.ts +++ b/packages/next/src/shared/lib/router/router.ts @@ -221,7 +221,12 @@ function getMiddlewareData( ) { const parsedSource = getNextPathnameInfo( parseRelativeUrl(source).pathname, - { parseData: true } + { + nextConfig: process.env.__NEXT_HAS_REWRITES + ? undefined + : nextConfig, + parseData: true, + } ) as = addBasePath(parsedSource.pathname) diff --git a/test/e2e/middleware-dynamic-basepath-matcher/app/middleware.js b/test/e2e/middleware-dynamic-basepath-matcher/app/middleware.js new file mode 100644 index 0000000000000..d4a6e6e00a89e --- /dev/null +++ b/test/e2e/middleware-dynamic-basepath-matcher/app/middleware.js @@ -0,0 +1,9 @@ +import { NextResponse } from 'next/server' + +export default function middleware(_) { + const res = NextResponse.next() + res.headers.set('X-From-Middleware', 'true') + return res +} + +export const config = { matcher: '/random' } diff --git a/test/e2e/middleware-dynamic-basepath-matcher/app/next.config.js b/test/e2e/middleware-dynamic-basepath-matcher/app/next.config.js new file mode 100644 index 0000000000000..1773c854e2959 --- /dev/null +++ b/test/e2e/middleware-dynamic-basepath-matcher/app/next.config.js @@ -0,0 +1,3 @@ +module.exports = { + basePath: '/base', +} diff --git a/test/e2e/middleware-dynamic-basepath-matcher/app/pages/[path]/[[...pages]].js b/test/e2e/middleware-dynamic-basepath-matcher/app/pages/[path]/[[...pages]].js new file mode 100644 index 0000000000000..7d7dd64f320a2 --- /dev/null +++ b/test/e2e/middleware-dynamic-basepath-matcher/app/pages/[path]/[[...pages]].js @@ -0,0 +1,35 @@ +import Link from 'next/link' +import { useRouter } from 'next/router' + +const Index = ({ value }) => { + const router = useRouter() + + return ( +
+

{value}

+

+ {router.query.path} +

+ + Link to another page + +
+ ) +} + +export async function getStaticPaths() { + return { + paths: [{ params: { path: 'another-page', pages: null } }], + fallback: true, + } +} + +export async function getStaticProps() { + return { + props: { + value: 'Hello', + }, + } +} + +export default Index diff --git a/test/e2e/middleware-dynamic-basepath-matcher/test/index.test.ts b/test/e2e/middleware-dynamic-basepath-matcher/test/index.test.ts new file mode 100644 index 0000000000000..07d4dc0051831 --- /dev/null +++ b/test/e2e/middleware-dynamic-basepath-matcher/test/index.test.ts @@ -0,0 +1,55 @@ +/* eslint-env jest */ +/* eslint-disable jest/no-standalone-expect */ + +import { join } from 'path' +import webdriver from 'next-webdriver' +import { fetchViaHTTP } from 'next-test-utils' +import { createNext, FileRef } from 'e2e-utils' +import { NextInstance } from 'test/lib/next-modes/base' + +const itif = (condition: boolean) => (condition ? it : it.skip) + +const isModeDeploy = process.env.NEXT_TEST_MODE === 'deploy' + +describe('Middleware custom matchers basePath', () => { + let next: NextInstance + + beforeAll(async () => { + next = await createNext({ + files: new FileRef(join(__dirname, '../app')), + }) + }) + afterAll(() => next.destroy()) + + // FIXME + // See https://linear.app/vercel/issue/EC-170/middleware-rewrite-of-nextjs-with-basepath-does-not-work-on-vercel + itif(!isModeDeploy)('should match', async () => { + for (const path of [ + '/base/default', + `/base/_next/data/${next.buildId}/default.json`, + ]) { + const res = await fetchViaHTTP(next.url, path) + expect(res.status).toBe(200) + expect(res.headers.get('x-from-middleware')).toBeDefined() + } + }) + + it.each(['/default', '/invalid/base/default'])( + 'should not match', + async (path) => { + const res = await fetchViaHTTP(next.url, path) + expect(res.status).toBe(404) + } + ) + + // FIXME: + // See https://linear.app/vercel/issue/EC-160/header-value-set-on-middleware-is-not-propagated-on-client-request-of + itif(!isModeDeploy)('should match query path', async () => { + const browser = await webdriver(next.url, '/base/random') + const currentPath = await browser.elementById('router-path').text() + expect(currentPath).toBe('random') + await browser.elementById('linkelement').click() + const anotherPagePath = await browser.elementById('router-path').text() + expect(anotherPagePath).toBe('another-page') + }) +})