diff --git a/packages/next/server/base-server.ts b/packages/next/server/base-server.ts index 8bf78489b307..78e51f1e708a 100644 --- a/packages/next/server/base-server.ts +++ b/packages/next/server/base-server.ts @@ -734,6 +734,7 @@ export default abstract class Server { match: getPathMatch('/_next/data/:path*'), type: 'route', name: '_next/data catchall', + check: true, fn: async (req, res, params, _parsedUrl) => { // Make sure to 404 for /_next/data/ itself and // we also want to 404 if the buildId isn't correct diff --git a/packages/next/server/router.ts b/packages/next/server/router.ts index 237188c8ca5e..1159d08e21d6 100644 --- a/packages/next/server/router.ts +++ b/packages/next/server/router.ts @@ -222,7 +222,14 @@ export default class Router { this.catchAllMiddleware const allRoutes = [ ...(middlewareCatchAllRoute - ? this.fsRoutes.filter((r) => r.name === '_next/data catchall') + ? this.fsRoutes + .filter((r) => r.name === '_next/data catchall') + .map((r) => { + return { + ...r, + check: false, + } + }) : []), ...this.headers, ...this.redirects, diff --git a/test/integration/custom-routes/next.config.js b/test/integration/custom-routes/next.config.js index c4bf06f3e0fc..3f9fc9bfcd23 100644 --- a/test/integration/custom-routes/next.config.js +++ b/test/integration/custom-routes/next.config.js @@ -204,6 +204,10 @@ module.exports = { source: '/blog/about', destination: '/hello', }, + { + source: '/overridden/:path*', + destination: '/overridden', + }, ], beforeFiles: [ { diff --git a/test/integration/custom-routes/pages/overridden/[slug].js b/test/integration/custom-routes/pages/overridden/[slug].js new file mode 100644 index 000000000000..16bd5c714b37 --- /dev/null +++ b/test/integration/custom-routes/pages/overridden/[slug].js @@ -0,0 +1,18 @@ +export default function Page() { + return

/overriden/[slug]

+} + +export function getStaticProps({ params }) { + return { + props: { + params, + }, + } +} + +export function getStaticPaths() { + return { + paths: [], + fallback: 'blocking', + } +} diff --git a/test/integration/custom-routes/test/index.test.js b/test/integration/custom-routes/test/index.test.js index a20ee0ab2297..55b60e85546a 100644 --- a/test/integration/custom-routes/test/index.test.js +++ b/test/integration/custom-routes/test/index.test.js @@ -39,6 +39,22 @@ let appPort let app const runTests = (isDev = false) => { + it('should not rewrite for _next/data route when a match is found', async () => { + const initial = await fetchViaHTTP(appPort, '/overridden/first') + expect(initial.status).toBe(200) + expect(await initial.text()).toContain('this page is overridden') + + const nextData = await fetchViaHTTP( + appPort, + `/_next/data/${buildId}/overridden/first.json` + ) + expect(nextData.status).toBe(200) + expect(await nextData.json()).toEqual({ + pageProps: { params: { slug: 'first' } }, + __N_SSG: true, + }) + }) + it('should handle has query encoding correctly', async () => { for (const expected of [ { @@ -1271,6 +1287,18 @@ const runTests = (isDev = false) => { slug: 'slug', }, }, + { + dataRouteRegex: `^\\/_next\\/data\\/${escapeRegex( + buildId + )}\\/overridden\\/([^\\/]+?)\\.json$`, + namedDataRouteRegex: `^/_next/data/${escapeRegex( + buildId + )}/overridden/(?[^/]+?)\\.json$`, + page: '/overridden/[slug]', + routeKeys: { + slug: 'slug', + }, + }, ], redirects: [ { @@ -2028,6 +2056,12 @@ const runTests = (isDev = false) => { regex: normalizeRegEx('^\\/blog\\/about(?:\\/)?$'), source: '/blog/about', }, + { + destination: '/overridden', + regex: + '^\\/overridden(?:\\/((?:[^\\/]+?)(?:\\/(?:[^\\/]+?))*))?(?:\\/)?$', + source: '/overridden/:path*', + }, ], fallback: [], }, @@ -2088,6 +2122,14 @@ const runTests = (isDev = false) => { slug: 'slug', }, }, + { + namedRegex: '^/overridden/(?[^/]+?)(?:/)?$', + page: '/overridden/[slug]', + regex: '^\\/overridden\\/([^\\/]+?)(?:\\/)?$', + routeKeys: { + slug: 'slug', + }, + }, ], staticRoutes: [ {