-
Notifications
You must be signed in to change notification settings - Fork 27.3k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix: infinite redirection loop when accessing user's preferred locale-prefixed path with middleware present #62435
Conversation
Allow CI Workflow Run
Note: this should only be enabled once the PR is ready to go and can only be enabled by a maintainer |
Stats from current PRDefault BuildGeneral Overall increase
|
vercel/next.js canary | masnormen/next.js fix/locale-detection-middleware-infinite-redirect | Change | |
---|---|---|---|
buildDuration | 13.8s | 13.8s | N/A |
buildDurationCached | 8.5s | 6.3s | N/A |
nodeModulesSize | 197 MB | 197 MB | |
nextStartRea..uration (ms) | 406ms | 403ms | N/A |
Client Bundles (main, webpack)
vercel/next.js canary | masnormen/next.js fix/locale-detection-middleware-infinite-redirect | Change | |
---|---|---|---|
2453-HASH.js gzip | 30.5 kB | 30.5 kB | N/A |
3304.HASH.js gzip | 181 B | 181 B | ✓ |
3f784ff6-HASH.js gzip | 53.7 kB | 53.7 kB | N/A |
8299-HASH.js gzip | 5.04 kB | 5.04 kB | N/A |
framework-HASH.js gzip | 45.2 kB | 45.2 kB | ✓ |
main-app-HASH.js gzip | 243 B | 242 B | N/A |
main-HASH.js gzip | 32.1 kB | 32.2 kB | N/A |
webpack-HASH.js gzip | 1.7 kB | 1.7 kB | N/A |
Overall change | 45.4 kB | 45.4 kB | ✓ |
Legacy Client Bundles (polyfills)
vercel/next.js canary | masnormen/next.js fix/locale-detection-middleware-infinite-redirect | Change | |
---|---|---|---|
polyfills-HASH.js gzip | 31 kB | 31 kB | ✓ |
Overall change | 31 kB | 31 kB | ✓ |
Client Pages
vercel/next.js canary | masnormen/next.js fix/locale-detection-middleware-infinite-redirect | Change | |
---|---|---|---|
_app-HASH.js gzip | 196 B | 197 B | N/A |
_error-HASH.js gzip | 184 B | 184 B | ✓ |
amp-HASH.js gzip | 505 B | 505 B | ✓ |
css-HASH.js gzip | 324 B | 325 B | N/A |
dynamic-HASH.js gzip | 2.5 kB | 2.5 kB | N/A |
edge-ssr-HASH.js gzip | 258 B | 258 B | ✓ |
head-HASH.js gzip | 352 B | 352 B | ✓ |
hooks-HASH.js gzip | 370 B | 371 B | N/A |
image-HASH.js gzip | 4.2 kB | 4.2 kB | ✓ |
index-HASH.js gzip | 259 B | 259 B | ✓ |
link-HASH.js gzip | 2.67 kB | 2.67 kB | N/A |
routerDirect..HASH.js gzip | 314 B | 312 B | N/A |
script-HASH.js gzip | 386 B | 386 B | ✓ |
withRouter-HASH.js gzip | 309 B | 309 B | ✓ |
1afbb74e6ecf..834.css gzip | 106 B | 106 B | ✓ |
Overall change | 6.56 kB | 6.56 kB | ✓ |
Client Build Manifests
vercel/next.js canary | masnormen/next.js fix/locale-detection-middleware-infinite-redirect | Change | |
---|---|---|---|
_buildManifest.js gzip | 483 B | 485 B | N/A |
Overall change | 0 B | 0 B | ✓ |
Rendered Page Sizes
vercel/next.js canary | masnormen/next.js fix/locale-detection-middleware-infinite-redirect | Change | |
---|---|---|---|
index.html gzip | 528 B | 526 B | N/A |
link.html gzip | 541 B | 539 B | N/A |
withRouter.html gzip | 523 B | 522 B | N/A |
Overall change | 0 B | 0 B | ✓ |
Edge SSR bundle Size
vercel/next.js canary | masnormen/next.js fix/locale-detection-middleware-infinite-redirect | Change | |
---|---|---|---|
edge-ssr.js gzip | 95 kB | 95 kB | N/A |
page.js gzip | 3.05 kB | 3.06 kB | N/A |
Overall change | 0 B | 0 B | ✓ |
Middleware size
vercel/next.js canary | masnormen/next.js fix/locale-detection-middleware-infinite-redirect | Change | |
---|---|---|---|
middleware-b..fest.js gzip | 624 B | 624 B | ✓ |
middleware-r..fest.js gzip | 151 B | 151 B | ✓ |
middleware.js gzip | 25.5 kB | 25.5 kB | N/A |
edge-runtime..pack.js gzip | 839 B | 839 B | ✓ |
Overall change | 1.61 kB | 1.61 kB | ✓ |
Next Runtimes
vercel/next.js canary | masnormen/next.js fix/locale-detection-middleware-infinite-redirect | Change | |
---|---|---|---|
app-page-exp...dev.js gzip | 171 kB | 171 kB | ✓ |
app-page-exp..prod.js gzip | 96.7 kB | 96.7 kB | ✓ |
app-page-tur..prod.js gzip | 98.5 kB | 98.5 kB | ✓ |
app-page-tur..prod.js gzip | 92.9 kB | 92.9 kB | ✓ |
app-page.run...dev.js gzip | 150 kB | 150 kB | ✓ |
app-page.run..prod.js gzip | 91.4 kB | 91.4 kB | ✓ |
app-route-ex...dev.js gzip | 21.3 kB | 21.3 kB | ✓ |
app-route-ex..prod.js gzip | 15 kB | 15 kB | ✓ |
app-route-tu..prod.js gzip | 15 kB | 15 kB | ✓ |
app-route-tu..prod.js gzip | 14.8 kB | 14.8 kB | ✓ |
app-route.ru...dev.js gzip | 20.9 kB | 20.9 kB | ✓ |
app-route.ru..prod.js gzip | 14.8 kB | 14.8 kB | ✓ |
pages-api-tu..prod.js gzip | 9.51 kB | 9.51 kB | ✓ |
pages-api.ru...dev.js gzip | 9.79 kB | 9.79 kB | ✓ |
pages-api.ru..prod.js gzip | 9.51 kB | 9.51 kB | ✓ |
pages-turbo...prod.js gzip | 22.3 kB | 22.3 kB | ✓ |
pages.runtim...dev.js gzip | 23 kB | 23 kB | ✓ |
pages.runtim..prod.js gzip | 22.3 kB | 22.3 kB | ✓ |
server.runti..prod.js gzip | 50.6 kB | 50.6 kB | ✓ |
Overall change | 950 kB | 950 kB | ✓ |
build cache
vercel/next.js canary | masnormen/next.js fix/locale-detection-middleware-infinite-redirect | Change | |
---|---|---|---|
0.pack gzip | 1.56 MB | 1.56 MB | N/A |
index.pack gzip | 105 kB | 105 kB | N/A |
Overall change | 0 B | 0 B | ✓ |
Diff details
Diff for middleware.js
Diff too large to display
Tests Passed |
is it possible that the test is flaky? it seems that the test gives different results everytime I run it locally. even when i removed my modification. |
@masnormen That one is indeed a flaky test! Taking a look at your |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hi, we shouldn't be relying on x-invoke-path
here as that is a local router-server
implementation detail that we want to eventually get rid of, I opened #62606 which has an alternative fix for this carrying over your test as well.
Hi. Yeah that's great too. Using headers directly does feel too hacky. |
This moves the locale redirect handling out of `base-server` as it shouldn't be handled here and should be at the routing level. This avoids the duplicate handling with middleware that causes the incorrect detection/infinite looping. Test case from separate PR was carried over to prevent regression. Fixes: #55648 Closes: #62435 Closes: NEXT-2627 Closes: NEXT-2628 --------- Co-authored-by: Nourman Hajar <nourmanhajar@gmail.com> Co-authored-by: samcx <sam@vercel.com>
What? / Why?
This PR will fix #55648.
When the
defaultLocale
of a Nextjs project is different than the user'spreferredLocale
, and user accesses that locale path, Next js somehow will infinitely redirect to the same page.defaultLocale
of Nextjs project is 'en'. And the project has other locale 'id'preferredLocale
(Accept-Language header) is 'id'This happens only when using a middleware.
How?
The function
getLocaleRedirect
seems to be called twice when we fetchGET /id
. One triggered somewhere when handling the middleware call (?), and one triggered somewhere ininvokeRender
in router-server.The first call correctly detect that the user is already on the right URL ('/id', as in the
preferredLocale
). But the second call somehow fails to determine it.I've noticed that only this second call of
getLocaleRedirect
is problematic, and the second call can be distinguished by the headerx-invoke-path
. Infinite redirect is solved by detecting if the invoke path is the same as current locale.