@@ -164,27 +164,33 @@ export const buildResponse = async ({
164
164
newRoute : rewriteUrl . pathname ,
165
165
basePath : nextConfig ?. basePath ,
166
166
} )
167
+ if ( rewriteUrl . toString ( ) === request . url ) {
168
+ logger . withFields ( { rewrite_url : rewrite } ) . debug ( 'Rewrite url is same as original url' )
169
+ return
170
+ }
171
+ res . headers . set ( 'x-middleware-rewrite' , relativeUrl )
172
+ return addMiddlewareHeaders ( fetch ( new Request ( rewriteUrl , request ) ) , res )
173
+ }
174
+ const target = normalizeLocalizedTarget ( { target : rewrite , request, nextConfig } )
175
+ if ( target === request . url ) {
176
+ logger . withFields ( { rewrite_url : rewrite } ) . debug ( 'Rewrite url is same as original url' )
177
+ return
167
178
}
168
179
res . headers . set ( 'x-middleware-rewrite' , relativeUrl )
169
- request . headers . set ( 'x-middleware-rewrite' , rewrite )
170
- return addMiddlewareHeaders ( fetch ( new Request ( rewriteUrl , request ) ) , res )
180
+ request . headers . set ( 'x-middleware-rewrite' , target )
181
+ return addMiddlewareHeaders ( fetch ( new Request ( target , request ) ) , res )
171
182
}
172
183
173
184
let redirect = res . headers . get ( 'location' )
174
185
175
186
// If we are redirecting a request that had a locale in the URL, we need to add it back in
176
187
if ( redirect && requestLocale ) {
177
- const redirectUrl = new URL ( redirect , request . url )
178
-
179
- const normalizedRedirect = normalizeLocalePath ( redirectUrl . pathname , nextConfig ?. i18n ?. locales )
180
-
181
- const locale = normalizedRedirect . detectedLocale ?? requestLocale
182
- // Pages router API routes don't have a locale in the URL
183
- if ( locale && ! redirectUrl . pathname . startsWith ( `/api/` ) ) {
184
- redirectUrl . pathname = `/${ locale } ${ normalizedRedirect . pathname } `
185
- redirect = redirectUrl . toString ( )
186
- res . headers . set ( 'location' , redirect )
188
+ redirect = normalizeLocalizedTarget ( { target : redirect , request, nextConfig } )
189
+ if ( redirect === request . url ) {
190
+ logger . withFields ( { rewrite_url : rewrite } ) . debug ( 'Rewrite url is same as original url' )
191
+ return
187
192
}
193
+ res . headers . set ( 'location' , redirect )
188
194
}
189
195
190
196
// Data requests shouldn't automatically redirect in the browser (they might be HTML pages): they're handled by the router
@@ -206,3 +212,34 @@ export const buildResponse = async ({
206
212
207
213
return res
208
214
}
215
+
216
+ /**
217
+ * Normalizes the locale in a URL.
218
+ */
219
+ function normalizeLocalizedTarget ( {
220
+ target,
221
+ request,
222
+ nextConfig,
223
+ requestLocale,
224
+ } : {
225
+ target : string
226
+ request : Request
227
+ nextConfig ?: RequestData [ 'nextConfig' ]
228
+ requestLocale ?: string
229
+ } ) {
230
+ const targetUrl = new URL ( target , request . url )
231
+
232
+ const normalizedTarget = normalizeLocalePath ( targetUrl . pathname , nextConfig ?. i18n ?. locales )
233
+
234
+ const locale = normalizedTarget . detectedLocale ?? requestLocale
235
+ if (
236
+ locale &&
237
+ ! normalizedTarget . pathname . startsWith ( `/api/` ) &&
238
+ ! normalizedTarget . pathname . startsWith ( `/_next/static/` )
239
+ ) {
240
+ targetUrl . pathname = `/${ locale } ${ normalizedTarget . pathname } `
241
+ return targetUrl . toString ( )
242
+ }
243
+ targetUrl . pathname = normalizedTarget . pathname
244
+ return targetUrl . toString ( )
245
+ }
0 commit comments