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

Dynamic Layout with Suspense hangs after 2nd navigation in Next 15 #72060

Closed
caleblloyd opened this issue Oct 30, 2024 · 9 comments · Fixed by #74552
Closed

Dynamic Layout with Suspense hangs after 2nd navigation in Next 15 #72060

caleblloyd opened this issue Oct 30, 2024 · 9 comments · Fixed by #74552
Labels
bug Issue was opened via the bug report template.

Comments

@caleblloyd
Copy link

Link to the code that reproduces this issue

https://github.com/caleblloyd/next-layout-cache-bug/

To Reproduce

npm install
npm run dev

To Reproduce

Navigate to http://localhost:3000/now

  1. "Now Page" loads fine initially
  2. Click "Home Page"
  3. Click "Now Page", it is stuck at the suspense and never makes the API call

Video of bug starting from Now Page

If you start at the Home Page things work fine

Navigate to http://localhost:3000

  1. Click on "Now Page", it works
  2. Click on "Home Page"
  3. Click on "Now Page" again, it works

Video of things working starting from Home Page

Current vs. Expected behavior

I am using a layout in a subdirectory of the app router. It should be dynamic because I am using export const dynamic = 'force-dynamic' on the layout.

If I load a page that uses this layout initially, then navigate away and navigate back, it gets stuck at the Suspense and LoadData is never called again. next dev has the static route indicator on the page upon navigating back.

If I load a page that does not use this layout initially, I can navigate to a page using the layout multiple times and it works. next dev does not have the static route indicator on the page.

import {ReactNode, Suspense} from "react"
import Link from "next/link";

export const dynamic = 'force-dynamic'

async function LoadData(props: { children: ReactNode }) {
  const response = await fetch(`http://localhost:3000/api`)
  const data = await response.json() as { now: number }
  return <>
    {props.children}
    <div>Got API Response at {data.now}</div>
  </>
}

export default async function Layout(props: { children: ReactNode }) {
  return <>
    <div><Link href={`/`} className="text-blue-500">Home Page</Link></div>
    <Suspense fallback={<h1>Loading... {Date.now()}</h1>}>
      <LoadData>{props.children}</LoadData>
    </Suspense>
  </>
}

Provide environment information

Operating System:
  Platform: linux
  Arch: x64
  Version: #45-Ubuntu SMP PREEMPT_DYNAMIC Fri Aug 30 12:02:04 UTC 2024
  Available memory (MB): 15718
  Available CPU cores: 4
Binaries:
  Node: 20.18.0
  npm: 10.8.2
  Yarn: N/A
  pnpm: 9.12.1
Relevant Packages:
  next: 15.0.3-canary.1 // Latest available version is detected (15.0.3-canary.1).
  eslint-config-next: 15.0.2
  react: 19.0.0-rc-02c0e824-20241028
  react-dom: 19.0.0-rc-02c0e824-20241028
  typescript: 5.6.3
Next.js Config:
  output: N/A

Which area(s) are affected? (Select all that apply)

Not sure

Which stage(s) are affected? (Select all that apply)

next dev (local), next start (local)

Additional context

No response

@caleblloyd caleblloyd added the bug Issue was opened via the bug report template. label Oct 30, 2024
@caleblloyd
Copy link
Author

On further investigation, the layout never reloads in next start no matter which page is loaded initially.

As a workaround, I am able to remove the <Suspense> in the Layout, and use layout.tsx instead:

image

I still feel like this is a bug though, because the Loading UI and Streaming documentation seems to indicate that custom Suspense boundaries should work

@caleblloyd caleblloyd changed the title Dynamic Layout getting incorrectly cached only when it is initial page load in Next 15 Dynamic Layout with Suspense hangs after 2nd navigation in Next 15 Oct 30, 2024
@Winwardo
Copy link

Winwardo commented Nov 13, 2024

Hi, I've been experiencing the same bug and it's blocked our upgrade from 14 -> 15.

EDIT: This does still repro with 15.0.4-canary.8, it just seems a bit less common, but that could just be randomness. I haven't been able to isolate a small repro repo like this issue, but navigating quickly through different pages on my project sometimes causes it to get stuck at Suspense boundaries inside the page, not in a Loading.tsx

Original, invalid

I've just tested again with 15.0.4-canary.8 and it appears to be fixed (I can once again navigate through my app back and forth without getting stuck at Suspense boundaries)
I've looked through both NextJS' and React's changelogs and obviously cannot see which commit may have fixed this - are you still seeing this on your repro?

@eps1lon
Copy link
Member

eps1lon commented Jan 6, 2025

Local bisecting lead to 15.0.0-canary.36 being the last good version i.e. it broke in 15.0.0-canary.37. Can somebody confirm that this is this is the same version that introduced this regression in their app?

@eps1lon
Copy link
Member

eps1lon commented Jan 6, 2025

Locally, I can no longer reproduce it starting with 15.0.3-canary.4. Can somebody confirm that it's fixed for them in 15.0.3-canary.4 and later i.e. latest canary? The latest stable should also be fixed i.e. 15.0.3 and later.

@caleblloyd
Copy link
Author

Looks like it is still an issue, but only in the production bundle with npm run build and npm run start

I updated the versions, instructions, and screencasts in the reproduction repo

@eps1lon
Copy link
Member

eps1lon commented Jan 6, 2025

Looks like it is still an issue, but only in the production bundle with npm run build and npm run start

That's what I also got. next dev is fixed but next start is still broken.

@nnnnoel
Copy link
Contributor

nnnnoel commented Jan 6, 2025

I think #72191 , #72227 or #72284 fixes issue from dev.
maybe prefetch or navigation cache is incompatible

@eugenefischer
Copy link

I'm encountering this in 15.1.3. A suspense boundary in layout.tsx works fine in dev, but not once built.

@caleblloyd
Copy link
Author

Validated that this is fixed in 15.2.0-canary.2. Thanks @eps1lon!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Issue was opened via the bug report template.
Projects
None yet
Development

Successfully merging a pull request may close this issue.

5 participants