vercel / next.js

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

Layout re-renders with each page in same dynamic route segment when middleware rewrite and prefetch={false} #52474

Open p00000001 opened 1 year ago

p00000001 commented 1 year ago

Verify canary release

Provide environment information

Operating System:
      Platform: win32
      Arch: x64
      Version: Windows 10 Home
    Binaries:
      Node: 18.16.0
      npm: N/A
      Yarn: N/A
      pnpm: N/A
    Relevant Packages:
      next: 13.4.10-canary.0
      eslint-config-next: N/A
      react: 18.2.0
      react-dom: 18.2.0
      typescript: 4.9.5
    Next.js Config:
      output: N/A

Which area(s) of Next.js are affected? (leave empty if unsure)

App Router

Link to the code that reproduces this issue or a replay of the bug

https://github.com/p00000001/next-routing-issue

To Reproduce

  1. Click Page A (browser path "/a" | rewrites to "/en/a")
  2. Click Page B (browser path "/b" | rewrites to "/en/b")
  3. Click Page C (browser path "/c" | rewrites to "/en/c")
  4. Click Page D (browser path "/d" | rewrites to "/en/d")
  5. [wait 30 seconds for client cache to expire]
  6. Click Page A

Describe the Bug

The layout and all pages are located under the same route segment:

/[locale]/layout.js /[locale]/a/page.js /[locale]/b/page.js /[locale]/c/page.js /[locale]/d/page.js

When Page A is requested, as expected both /[locale]/layout.js and /[locale]/a/page.js are rendered.

However, when Page B/C/D are requested /[locale]/layout.js is rendered again each time, despite all pages being under the same route segment.

This only happens the first time the pages are requested. Subsequent requests to a previously loaded page, performs as expected and only renders the page and not the layout again. This can be seen in step (6) when Page A is revisited.

It should be noted that two condition appear to be required for the bug to occur:

  1. On the Link component prefetch={false}. Setting prefetch={true} seems to resolve it but this is not suitable for our project.
  2. The middleware rewrites the browser URL. For example, when explicitly including the locale in the browser URL e.g. /fr/a then the issue does not occur. However, this would mean we cannot support a default locale URL

Expected Behavior

Page A/B/C/D are all under the same route segment and share the same layout. Therefore /[locale]/layout.js should only be rendered with the first page request and not subsequent ones.

Particularly as out layouts require API fetches, it can slow down page transitions.

Which browser are you using? (if relevant)

Chrome latest

How are you deploying your application? (if relevant)

Next start

p00000001 commented 1 year ago

Similarities to #50670 but no middleware rewrite in that issue, which appears critical here

cbratschi commented 9 months ago

There is a discussion here:

https://github.com/vercel/next.js/discussions/50711