Skip to content
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

[i18n] non-default locale root level routes (i.e. /fr /es) get 307 redirects to themselves? #21943

Closed
lindsaylevine opened this issue Feb 7, 2021 · 6 comments · Fixed by #22445
Labels
bug Issue was opened via the bug report template.

Comments

@lindsaylevine
Copy link
Contributor

What version of Next.js are you using?

10.0.6

What version of Node.js are you using?

14.12.0

What browser are you using?

Chrome

What operating system are you using?

macOS

How are you deploying your application?

Other platform

Describe the Bug

i18n + target: serverless

this line is true only for non-default locale root routes (aka /pl or /fr etc). when shouldAddLocalePrefix is true, it passes this condition (which therefore fails for non-root routes like /pl/static) and sets up a 307 to /pl, which can cause infinite redirects.

i'm looking to better understand why this logic exists for root non-default locale pages in i18n. specifically, this line:

const shouldAddLocalePrefix = !detectedDefaultLocale && denormalizedPagePath === '/'

what is the purpose of this condition? denormalizedPagePath becomes / when req.url is /fr or /pl. so like i said, it will eventually get to the res.setHeader and formatUrl using this value ${basePath || ''}/${detectedLocale} which becomes /fr or /pl. the problem with this is if you're serving next page (.next/serverless/pages/index.js) for /${locale}, the 307 will hit /${locale} again, reprocess the next page, re-hit the 307, etc etc.

i traced this work back to @ijjk so i assume they'll have the most insight :)

Expected Behavior

no 307s from /${locale} to /${locale}

To Reproduce

this is mainly just a question to understand so no need to repro. as answered previously though, yes, this is observed on a platform that is not vercel. my hope is that next maintainers are still diligent about helping those who don't or can't host on vercel! 🙏

thanks so much for your time and help! really appreciate it <3

@lindsaylevine lindsaylevine added the bug Issue was opened via the bug report template. label Feb 7, 2021
@ijjk
Copy link
Member

ijjk commented Feb 8, 2021

Hi, in the above lines in next-server the denormalizedPagePath for /fr should still be /fr as the URL pathname is being used and the denormalizePagePath util handles normalizing index paths. We don't see this behavior with next start or in our tests so this seems like it'd be more specific to the i18n handling in the serverless loader.

@lindsaylevine
Copy link
Contributor Author

lindsaylevine commented Feb 8, 2021

@ijjk hey thanks for the response :). i think denormalizedPagePath is "/" because this format turns /pl into /, because localePathResult per const localePathResult = normalizeLocalePath(pathname!, i18n.locales) becomes { pathname: '/', detectedLocale: 'pl' }. i can confirm in the bundled source here

Screen Shot 2021-02-08 at 3 44 24 PM

that at this point, parsedUrl.pathname is still /pl

Screen Shot 2021-02-08 at 3 45 19 PM

that said, it seems normalizeLocalePath is the primary suspect. from within normalizeLocalePath:

if (pathnameParts[1].toLowerCase() === locale.toLowerCase()) {
      detectedLocale = locale
      pathnameParts.splice(1, 1)
      pathname = pathnameParts.join('/') || '/'
      return true
    }
    return false

for a pathname/pl, the condition would be true, detectedLocale becomes pl, pathnameParts.splice(1,1) makes pathnameParts become [""] and so pathname becomes /

i'm v confused how this isnt an issue on next start / vercel assuming your req.url and parsedUrl.pathname are also /pl or /fr when the request is received 🤔

@lindsaylevine
Copy link
Contributor Author

lindsaylevine commented Feb 8, 2021

update (since i was double checking the value of parsedUrl.pathname after the req.url format call because parsedUrl.pathname is what's passed to normalizeLocalePath):

Screen Shot 2021-02-08 at 4 03 30 PM

i'm not sure whereabouts in the source this particular line in the bundle comes from (line 5714 ^).... but this is definitely the culprit in terms of parsedUrl.pathname becoming / and therefore denormalizedPagePath becoming /

Screen Shot 2021-02-08 at 6 14 09 PM

@lindsaylevine
Copy link
Contributor Author

@ijjk hey jj, sorry for the ping. able to offer any thoughts on this quickly? much appreciated 🙏

@ijjk
Copy link
Member

ijjk commented Feb 19, 2021

Hi, just double checked and in next-server we update req.url on the line you shared above since we don't include the locale in the req.url similar to our basePath handling but the pathname value is not updated here since it's parsed before that update and that is the value we check against.

I logged out the values after these lines for better visibility running against the test/integration/i18n-support suite:

$ node --trace-deprecation packages/next/dist/bin/next test/integration/i18n-support/
ready - started server on 0.0.0.0:3000, url: http://localhost:3000
info  - Using external babel configuration from /Users/jj/dev/vercel/next.js/test/.babelrc
{
  pathname: '/nl',
  detectedLocale: 'nl',
  shouldAddLocalePrefix: false,
  parsedUrlPathname: '/nl',
  denormalizedPagePath: '/nl',
  detectedDefaultLocale: false,
  shouldStripDefaultLocale: false
}

It looks like this value is being updated in the serverless handler here and used here which is causing the behavior noted above, correcting that should resolve the issue. Thanks for helping investigate this, feel free to send a PR updating this and we can get this updated!

lindsaylevine added a commit to lindsaylevine/next.js that referenced this issue Feb 23, 2021
@kodiakhq kodiakhq bot closed this as completed in #22445 Feb 25, 2021
kodiakhq bot pushed a commit that referenced this issue Feb 25, 2021
…rless handler (#22445)

Fixes #21943

i confirmed in a personal test repo that this solves the issue of infinite 307s on root level non-default locales :)  let me know what else this needs if anything! thanks for the time/help @ijjk ❤️
@balazsorban44
Copy link
Member

This issue has been automatically locked due to no recent activity. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

@vercel vercel locked as resolved and limited conversation to collaborators Jan 28, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
bug Issue was opened via the bug report template.
Projects
None yet
3 participants