7
7
addBasePath ,
8
8
normalizeDataUrl ,
9
9
normalizeLocalePath ,
10
+ normalizeTrailingSlash ,
10
11
relativizeURL ,
11
- rewriteDataPath ,
12
12
} from './util.ts'
13
13
import { addMiddlewareHeaders , isMiddlewareRequest , isMiddlewareResponse } from './middleware.ts'
14
14
import { RequestData } from './next-request.ts'
@@ -116,10 +116,21 @@ export const buildResponse = async ({
116
116
const res = new Response ( result . response . body , result . response )
117
117
request . headers . set ( 'x-nf-next-middleware' , 'skip' )
118
118
119
- const rewrite = res . headers . get ( 'x-middleware-rewrite' )
119
+ let rewrite = res . headers . get ( 'x-middleware-rewrite' )
120
+ let redirect = res . headers . get ( 'location' )
120
121
121
122
// Data requests (i.e. requests for /_next/data ) need special handling
122
123
const isDataReq = request . headers . has ( 'x-nextjs-data' )
124
+ // Data requests need to be normalized to the route path
125
+ if ( isDataReq && ! redirect && ! rewrite ) {
126
+ const requestUrl = new URL ( request . url )
127
+ const normalizedDataUrl = normalizeDataUrl ( requestUrl . pathname )
128
+ // Don't rewrite unless the URL has changed
129
+ if ( normalizedDataUrl !== requestUrl . pathname ) {
130
+ rewrite = `${ normalizedDataUrl } ${ requestUrl . search } `
131
+ logger . withFields ( { rewrite_url : rewrite } ) . debug ( 'Rewritten data URL' )
132
+ }
133
+ }
123
134
124
135
if ( rewrite ) {
125
136
logger . withFields ( { rewrite_url : rewrite } ) . debug ( 'Found middleware rewrite' )
@@ -132,7 +143,6 @@ export const buildResponse = async ({
132
143
}
133
144
134
145
const relativeUrl = relativizeURL ( rewrite , request . url )
135
- const originalPath = new URL ( request . url , `http://n` ) . pathname
136
146
137
147
if ( isDataReq ) {
138
148
// Data requests might be rewritten to an external URL
@@ -165,31 +175,24 @@ export const buildResponse = async ({
165
175
}
166
176
167
177
return addMiddlewareHeaders ( fetch ( proxyRequest , { redirect : 'manual' } ) , res )
168
- } else if ( isDataReq ) {
169
- rewriteUrl . pathname = rewriteDataPath ( {
170
- dataUrl : originalPath ,
171
- newRoute : rewriteUrl . pathname ,
172
- basePath : nextConfig ?. basePath ,
173
- } )
174
- if ( rewriteUrl . toString ( ) === request . url ) {
175
- logger . withFields ( { rewrite_url : rewrite } ) . debug ( 'Rewrite url is same as original url' )
176
- return
177
- }
178
- res . headers . set ( 'x-middleware-rewrite' , relativeUrl )
179
- return addMiddlewareHeaders ( fetch ( new Request ( rewriteUrl , request ) ) , res )
180
178
}
181
- const target = normalizeLocalizedTarget ( { target : rewrite , request, nextConfig } )
179
+
180
+ if ( isDataReq ) {
181
+ // The rewrite target is a data request, but a middleware rewrite target is always for the page route,
182
+ // so we need to tell the server this is a data request. Setting the `x-nextjs-data` header is not enough. 🤷
183
+ rewriteUrl . searchParams . set ( '__nextDataReq' , '1' )
184
+ rewriteUrl . pathname = normalizeTrailingSlash ( rewriteUrl . pathname , nextConfig ?. trailingSlash )
185
+ }
186
+ const target = normalizeLocalizedTarget ( { target : rewriteUrl . toString ( ) , request, nextConfig } )
182
187
if ( target === request . url ) {
183
188
logger . withFields ( { rewrite_url : rewrite } ) . debug ( 'Rewrite url is same as original url' )
184
189
return
185
190
}
186
191
res . headers . set ( 'x-middleware-rewrite' , relativeUrl )
187
192
request . headers . set ( 'x-middleware-rewrite' , target )
188
- return addMiddlewareHeaders ( fetch ( new Request ( target , request ) ) , res )
193
+ return addMiddlewareHeaders ( fetch ( new Request ( target , request ) , { redirect : 'manual' } ) , res )
189
194
}
190
195
191
- let redirect = res . headers . get ( 'location' )
192
-
193
196
// If we are redirecting a request that had a locale in the URL, we need to add it back in
194
197
if ( redirect && requestLocale ) {
195
198
redirect = normalizeLocalizedTarget ( { target : redirect , request, nextConfig } )
0 commit comments