vercel / next.js

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

Suspense does not work as expected in Page Router index.js #66768

Open pkellner opened 1 month ago

pkellner commented 1 month ago

Link to the code that reproduces this issue

https://github.com/pkellner/nextjs-15-rc-suspense-page-router-issue

To Reproduce

run next dev and browse to localhost:3000. This runs /pages/index.js and you should see a loading message that should have been generated from the Suspense fallback. The exact same code (but with 'use client' at the top) is working in the /app/test/page.js (localhost:3000/test)

Current vs. Expected behavior

Expect localhost:3000 to show loading message for 2 seconds before rendering list and it does not.

Provide environment information

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 23.5.0: Wed May  1 20:17:33 PDT 2024; root:xnu-10063.121.3~5/RELEASE_ARM64_T6031
  Available memory (MB): 65536
  Available CPU cores: 16
Binaries:
  Node: 20.10.0
  npm: 10.2.3
  Yarn: 1.22.21
  pnpm: 8.15.4
Relevant Packages:
  next: 15.0.0-rc.0 // Latest available version is detected (15.0.0-rc.0).
  eslint-config-next: N/A
  react: 19.0.0-rc-6230622a1a-20240610
  react-dom: 19.0.0-rc-6230622a1a-20240610
  typescript: N/A
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)

Additional context

I plan on upgrading old projects that use the page router to use client only suspense which is supported in React 19. I expect that it should work exactly the same as when 'use client' is put at the top of the page.ts file in the app folder.

icyJoseph commented 1 month ago

I wonder if this is because the SSR pass is using the non-streaming Server Side APIs, renderToNodeStream for example, which are at the core of Page Router.

We can see that, if we defer to client side only rendering, then the Suspense boundary does get triggered.

In the docs for, renderToNodeStream, we find:

This method will wait for all Suspense boundaries to complete before returning any output.

It'd seem like, this what happens in your repository.