vercel / next.js

The React Framework
https://nextjs.org
MIT License
125.9k stars 26.87k forks source link

"handleHardNavigation" causing infinite reload when on defaultLocale site #39399

Open vantezzen opened 2 years ago

vantezzen commented 2 years ago

Verify canary release

Provide environment information

Operating System:
  Platform: win32
  Arch: x64
  Version: Windows 10 Pro
Binaries:
  Node: 16.12.0
  npm: N/A
  Yarn: N/A
  pnpm: N/A
Relevant packages:
  next: 12.2.4-canary.12
  eslint-config-next: 12.2.4
  react: 18.2.0
  react-dom: 18.2.0

What browser are you using? (if relevant)

Chrome 100.0.4896.127

How are you deploying your application? (if relevant)

Vercel

Describe the Bug

"handleHardNavigation" in the Router (router.ts) assumes that the locale is always present in the current URL if i18n is enabled.

My code caused an internal Next.js error, which triggered "handleRouteInfoError" which then calls "handleHardNavigation" ("Error: Failed to lookup route: /_next/data/...json").

This caused the site to infinitely reload, making it harder to debug. Looking at the implementation, "handleHardNavigation" should prevent infinite reloads by comparing the URL:

https://github.com/vercel/next.js/blob/cd3e054f14ce38f4ff57c727a997da2a6e1d05dd/packages/next/shared/lib/router/router.ts#L574-L576

My next.config.js contains this code:

i18n: {
    locales: ["en", "de"],
    defaultLocale: "en",
},

Due to this, a page can be accessed at example.com/en/mypage, example.com/de/mypage and example.com/mypage. Stepping through the debugger, it seems like handleHardNavigation doesn't handle the third case if i18n is enabled. In my case, url is /mypage but addBasePath(addLocale(router.asPath, router.locale)) returns /en/mypage so the check returns false event though it is the same page.

This could be fixed by a change like this:

if (
  url === addBasePath(addLocale(router.asPath, router.locale)) ||
  (
    router.locale === router.defaultLocale &&
    url === addBasePath(router.asPath)
  )
) {

Possibly linked to #39361 but I couldn't check as their reproduction is password protected.

Expected Behavior

"handleHardNavigation" should not cause an infinite reload even if the default locale is used.

Link to reproduction

I tried creating a repro but I couldn't find a way to intentionally trigger "handleRouteInfoError" - if there is a way please let me know and I can provide a repo

To Reproduce

  1. Have code that triggers "handleRouteInfoError" some way or another
  2. Have Nextjs set up to use i18n
  3. Visit the page without prepending the locale to it
  4. Page infinitely reloads trying to get to a working page
willemliufdmg commented 2 years ago

May be related to:

Even though above ticket has been closed. The problem has never been solved.