Skip to content

Commit 5a602c3

Browse files
authoredJan 7, 2025
fix: adjust middleware json data rewrite to work with recent next@canary (#2734)
* fix: keep __nextDataReq query param working * fix: don't attempt to keep old query param working * test: remove tests that don't make sense anymore and update some other ones
1 parent c3e328c commit 5a602c3

File tree

9 files changed

+39
-32
lines changed

9 files changed

+39
-32
lines changed
 

‎edge-runtime/lib/response.ts

+10-6
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@ import {
1414
normalizeLocalePath,
1515
normalizeTrailingSlash,
1616
relativizeURL,
17+
removeBasePath,
18+
rewriteDataPath,
1719
} from './util.ts'
1820

1921
export interface FetchEventResult {
@@ -180,14 +182,16 @@ export const buildResponse = async ({
180182
}
181183

182184
if (isDataReq) {
183-
// The rewrite target is a data request, but a middleware rewrite target is always for the page route,
184-
// so we need to tell the server this is a data request. Setting the `x-nextjs-data` header is not enough. 🤷
185-
rewriteUrl.searchParams.set('__nextDataReq', '1')
185+
rewriteUrl.pathname = rewriteDataPath({
186+
dataUrl: new URL(request.url).pathname,
187+
newRoute: removeBasePath(rewriteUrl.pathname, nextConfig?.basePath),
188+
basePath: nextConfig?.basePath,
189+
})
190+
} else {
191+
// respect trailing slash rules to prevent 308s
192+
rewriteUrl.pathname = normalizeTrailingSlash(rewriteUrl.pathname, nextConfig?.trailingSlash)
186193
}
187194

188-
// respect trailing slash rules to prevent 308s
189-
rewriteUrl.pathname = normalizeTrailingSlash(rewriteUrl.pathname, nextConfig?.trailingSlash)
190-
191195
const target = normalizeLocalizedTarget({ target: rewriteUrl.toString(), request, nextConfig })
192196
if (target === request.url) {
193197
logger.withFields({ rewrite_url: rewrite }).debug('Rewrite url is same as original url')

‎tests/e2e/edge-middleware.test.ts

+17
Original file line numberDiff line numberDiff line change
@@ -52,3 +52,20 @@ test('it should render OpenGraph image meta tag correctly', async ({ page, middl
5252
const size = await getImageSize(Buffer.from(imageBuffer), 'png')
5353
expect([size.width, size.height]).toEqual([1200, 630])
5454
})
55+
56+
test('json data rewrite works', async ({ middlewarePages }) => {
57+
const response = await fetch(`${middlewarePages.url}/_next/data/build-id/sha.json`, {
58+
headers: {
59+
'x-nextjs-data': '1',
60+
},
61+
})
62+
63+
expect(response.ok).toBe(true)
64+
const body = await response.text()
65+
66+
expect(body).toMatch(/^{"pageProps":/)
67+
68+
const data = JSON.parse(body)
69+
70+
expect(data.pageProps.message).toBeDefined()
71+
})

‎tests/fixtures/middleware-pages/next-env.d.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
/// <reference types="next/image-types/global" />
33

44
// NOTE: This file should not be edited
5-
// see https://nextjs.org/docs/basic-features/typescript for more information.
5+
// see https://nextjs.org/docs/pages/api-reference/config/typescript for more information.

‎tests/fixtures/middleware-pages/next.config.js

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ if (platform === 'win32') {
2121
}
2222
}
2323

24+
/** @type {import('next').NextConfig} */
2425
module.exports = {
2526
trailingSlash: true,
2627
output: 'standalone',

‎tests/fixtures/middleware-pages/package.json

+3-1
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
"react-dom": "18.2.0"
1414
},
1515
"devDependencies": {
16-
"@types/react": "18.2.47"
16+
"@types/node": "^20.10.6",
17+
"@types/react": "18.2.47",
18+
"typescript": "^5.3.3"
1719
}
1820
}

‎tests/fixtures/middleware-pages/tsconfig.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,8 @@
1111
"moduleResolution": "node",
1212
"resolveJsonModule": true,
1313
"isolatedModules": true,
14-
"jsx": "preserve"
14+
"jsx": "preserve",
15+
"target": "ES2017"
1516
},
1617
"include": ["next-env.d.ts", "**/*.ts", "**/*.tsx"],
1718
"exclude": ["node_modules"]

‎tests/integration/edge-handler.test.ts

+4-7
Original file line numberDiff line numberDiff line change
@@ -387,8 +387,7 @@ describe('page router', () => {
387387
})
388388
const res = await response.json()
389389
const url = new URL(res.url, 'http://n/')
390-
expect(url.pathname).toBe('/ssr-page-2/')
391-
expect(url.searchParams.get('__nextDataReq')).toBe('1')
390+
expect(url.pathname).toBe('/_next/data/build-id/ssr-page-2.json')
392391
expect(res.headers['x-nextjs-data']).toBe('1')
393392
expect(response.headers.get('x-nextjs-rewrite')).toBe('/ssr-page-2/')
394393
expect(response.status).toBe(200)
@@ -420,7 +419,7 @@ describe('page router', () => {
420419
expect(response.status).toBe(200)
421420
})
422421

423-
test<FixtureTestContext>('should rewrite un-rewritten data requests to page route', async (ctx) => {
422+
test<FixtureTestContext>('should NOT rewrite un-rewritten data requests to page route', async (ctx) => {
424423
await createFixture('middleware-pages', ctx)
425424
await runPlugin(ctx)
426425
const origin = await LocalServer.run(async (req, res) => {
@@ -443,8 +442,7 @@ describe('page router', () => {
443442
})
444443
const res = await response.json()
445444
const url = new URL(res.url, 'http://n/')
446-
expect(url.pathname).toBe('/ssg/hello/')
447-
expect(url.searchParams.get('__nextDataReq')).toBe('1')
445+
expect(url.pathname).toBe('/_next/data/build-id/ssg/hello.json')
448446
expect(res.headers['x-nextjs-data']).toBe('1')
449447
expect(response.status).toBe(200)
450448
})
@@ -472,8 +470,7 @@ describe('page router', () => {
472470
})
473471
const res = await response.json()
474472
const url = new URL(res.url, 'http://n/')
475-
expect(url.pathname).toBe('/blog/first/')
476-
expect(url.searchParams.get('__nextDataReq')).toBe('1')
473+
expect(url.pathname).toBe('/_next/data/build-id/blog/first.json')
477474
expect(url.searchParams.get('slug')).toBe('first')
478475
expect(res.headers['x-nextjs-data']).toBe('1')
479476
expect(response.status).toBe(200)

‎tests/integration/page-router.test.ts

-16
Original file line numberDiff line numberDiff line change
@@ -95,22 +95,6 @@ test<FixtureTestContext>('Should revalidate path with On-demand Revalidation', a
9595
expect(dateCacheInitial).not.toBe(dateCacheRevalidated)
9696
})
9797

98-
test<FixtureTestContext>('Should return JSON for data req to page route', async (ctx) => {
99-
await createFixture('page-router', ctx)
100-
await runPlugin(ctx)
101-
102-
const response = await invokeFunction(ctx, {
103-
url: '/static/revalidate-manual?__nextDataReq=1',
104-
headers: { 'x-nextjs-data': '1' },
105-
})
106-
107-
expect(response.body).toMatch(/^{"pageProps":/)
108-
109-
const data = JSON.parse(response.body)
110-
111-
expect(data.pageProps.show).toBeDefined()
112-
})
113-
11498
test.skipIf(platform === 'win32')<FixtureTestContext>(
11599
'Should set permanent "netlify-cdn-cache-control" header on fully static pages"',
116100
async (ctx) => {

‎tests/utils/create-e2e-fixture.ts

+1
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,7 @@ export const fixtureFactories = {
325325
bun: () => createE2EFixture('simple', { packageManger: 'bun' }),
326326
middleware: () => createE2EFixture('middleware'),
327327
middlewareOg: () => createE2EFixture('middleware-og'),
328+
middlewarePages: () => createE2EFixture('middleware-pages'),
328329
pageRouter: () => createE2EFixture('page-router'),
329330
pageRouterBasePathI18n: () => createE2EFixture('page-router-base-path-i18n'),
330331
turborepo: () =>

0 commit comments

Comments
 (0)
Please sign in to comment.