@@ -21,6 +21,7 @@ class RoutesMatcher {
21
21
* @param {object } routes The processed Vercel build output config routes.
22
22
* @param {object } output Vercel build output.
23
23
* @param {object } reqCtx Request context object; request object, assets fetcher, and execution context.
24
+ * @param {Array } buildMetadata Information about the build to be used in the routing.
24
25
* @returns {void } The matched set of path, status, headers, and search params.
25
26
*/
26
27
constructor (
@@ -30,6 +31,7 @@ class RoutesMatcher {
30
31
output ,
31
32
/** Request Context object for the request to match */
32
33
reqCtx ,
34
+ buildMetadata ,
33
35
) {
34
36
this . routes = routes ;
35
37
this . output = output ;
@@ -47,6 +49,7 @@ class RoutesMatcher {
47
49
48
50
this . checkPhaseCounter = 0 ;
49
51
this . middlewareInvoked = [ ] ;
52
+ this . locales = new Set ( buildMetadata ) ;
50
53
}
51
54
52
55
/**
@@ -238,7 +241,8 @@ class RoutesMatcher {
238
241
* @returns {string }The previous path for the route before applying the destination.
239
242
*/
240
243
applyRouteDest ( route , srcMatch , captureGroupKeys ) {
241
- if ( ! route . dest ) return this . path ;
244
+ const localesMatchesRoute = this . locales . has ( route . dest ?. replace ( '/' , '' ) ) ;
245
+ if ( ! route . dest || localesMatchesRoute ) return this . path ;
242
246
243
247
const prevPath = this . path ;
244
248
@@ -476,6 +480,23 @@ class RoutesMatcher {
476
480
return 'done' ;
477
481
}
478
482
483
+ if ( phase === 'none' ) {
484
+ // applications using the Pages router with i18n plus a catch-all root route
485
+ // redirect all requests (including /api/ ones) to the catch-all route, the only
486
+ // way to prevent this erroneous behavior is to remove the locale here if the
487
+ // path without the locale exists in the vercel build output
488
+ // eslint-disable-next-line no-restricted-syntax
489
+ for ( const locale of this . locales ) {
490
+ const localeRegExp = new RegExp ( `/${ locale } (/.*)` ) ;
491
+ const match = this . path . match ( localeRegExp ) ;
492
+ const pathWithoutLocale = match ?. [ 1 ] ;
493
+ if ( pathWithoutLocale && pathWithoutLocale in this . output ) {
494
+ this . path = pathWithoutLocale ;
495
+ break ;
496
+ }
497
+ }
498
+ }
499
+
479
500
let pathExistsInOutput = this . path in this . output ;
480
501
481
502
// If a path with a trailing slash entered the `rewrite` phase and didn't find a match, it might
0 commit comments