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 import with suspense:true, ssr:false causes The server could not finish this Suspense boundary error #36636

Closed
1 task done
flybayer opened this issue May 3, 2022 · 13 comments · Fixed by #36825
Closed
1 task done
Assignees
Labels
bug Issue was opened via the bug report template.

Comments

@flybayer
Copy link
Contributor

flybayer commented May 3, 2022

Verify canary release

  • I verified that the issue exists in Next.js canary release

Provide environment information

Operating System:
  Platform: darwin
  Arch: arm64
  Version: Darwin Kernel Version 21.2.0: Sun Nov 28 20:28:41 PST 2021; root:xnu-8019.61.5~1/RELEASE_ARM64_T6000
Binaries:
  Node: 16.14.2
  npm: 8.1.4
  Yarn: 1.22.1
  pnpm: 6.32.4
Relevant packages:
  next: 12.1.6-canary.16
  react: 18.1.0
  react-dom: 18.1.0

Describe the Bug

Using dynamic component import with {suspense: true, ssr:false} cause this error:

Error: The server could not finish this Suspense boundary, likely due to an error during server rendering. Switched to client rendering.

image

Important Note: functionally this works correctly, the issue is just that an error is being generated and so it appears broken

Expected Behavior

Should work without any error popup or error in browser console

To Reproduce

Runable reproduction: https://codesandbox.io/s/dank-sound-pkxopr?file=/pages/index.js

import { Suspense } from "react";
import dynamic from "next/dynamic";

const Thing = dynamic(() => import("../thing"), { ssr: false, suspense: true });

export default function IndexPage() {
  return (
    <div>
      <p>Next.js Example</p>
      <Suspense fallback="Loading...">
        <Thing />
      </Suspense>
    </div>
  );
}
//thing.js
export default function Thing() {
  return "Thing";
}

Other

You can also cause this same behavior with this next.js page:

import { Suspense } from "react";

export default function Thing() {
  if (typeof window === 'undefined') {
    const e = new error()
    e.name = "rendering suspense fallback..."
    delete e.stack
    throw e
  } 
  return "Thing"
}

export default function IndexPage() {
  return (
    <div>
      <p>Next.js Example</p>
      <Suspense fallback="Loading...">
        <Thing />
      </Suspense>
    </div>
  );
}
@flybayer flybayer added the bug Issue was opened via the bug report template. label May 3, 2022
@flybayer flybayer changed the title dynamic import with suspense:true & ssr:false causes The server could not finish this Suspense boundary error dynamic import with suspense:true, ssr:false causes The server could not finish this Suspense boundary error May 3, 2022
@huozhi
Copy link
Member

huozhi commented May 3, 2022

You can remove the ssr option for now since suspense: true will use React.lazy for dynamic components. Or you can use React.lazy directly. It compiles a bit incorrectly with ssr and suspense option together, we'll fix it

@flybayer
Copy link
Contributor Author

flybayer commented May 3, 2022

@huozhi removing ssr:false doesn't work because it doesn't render suspense fallback (it renders nothing instead)

@Brooooooklyn Brooooooklyn self-assigned this May 4, 2022
@bkyerv
Copy link

bkyerv commented May 10, 2022

I wonder if there is any progress with that? In case I was trying tutorial with useSWR and suspense and I don't need all the latest functionalities how could I use earlier versions of the next and react?

@kodiakhq kodiakhq bot closed this as completed in #36825 May 17, 2022
kodiakhq bot pushed a commit that referenced this issue May 17, 2022
The Babel plugin works fine, so it seems not a runtime issue.

fixes #36636
@shkreios
Copy link

shkreios commented May 20, 2022

It appears that this still doesn't work as expected. I adapted the codesandbox, to use ssr: false and let the Thing component try to access the window object.

By doing this the app throws an error again because the component is getting rendered on the backend.

https://codesandbox.io/s/cool-dew-oengrx?file=/pages/index.js

@bkyerv
Copy link

bkyerv commented May 27, 2022

still experiencing this issue

@timneutkens
Copy link
Member

@bkyerv are you using next@canary or stable? If stable then please use next@canary to check if you're still running into it.

@bkyerv
Copy link

bkyerv commented May 30, 2022

I use @canary but about a week ago version of canary. I will try @canary one more time tonight and report back if I succeeded.

@huozhi
Copy link
Member

huozhi commented May 30, 2022

@shkreios That's because react will resolve the suspense on server side with react lazy, so if you throw an error (calling dom api on server side for your case) SSR will fail. In the future we might introduce some way to let you skip the error. But the behavior is as expected now.

@sidwebworks
Copy link
Contributor

Any progress on this? I have a similiar requirement of using ssr: false with suspense:true

@huozhi
Copy link
Member

huozhi commented Jun 1, 2022

React trying to resolve the suspense on server side with suspense mode next/dynamic is the expected behavior, which means if you throw error there it will certainly fail in SSR. ssr option won't effect if suspense option is set to true. The previous fix @Brooooooklyn did is more about the compilation side to make sure the options are passed down properly.

What we can change the behavior in the future is to track all recoverable react rendering errors thrown on server side and decide which one can be dropped. It's not able to achieve with the current version, we're still designing the solution for it in progress. I'll close this issue for now and once we'll post more details in community once we have a clear solution

@huozhi huozhi closed this as completed Jun 1, 2022
@graup
Copy link

graup commented Jun 24, 2022

Is there any workaround for this? How to fix code that throws on server? We have a page component with a hook that needs to be run on the client. It throws on pre-rendering with ssr: false and suspense: true.

@github-actions
Copy link
Contributor

This closed issue has been automatically locked because it had no new activity for a month. If you are running into a similar issue, please create a new issue with the steps to reproduce. Thank you.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Jul 24, 2022
@huozhi
Copy link
Member

huozhi commented Dec 14, 2022

Update: you could try the latest canary (>= 13.0.7-canary.5) now, we have migrated next/dynamic to Suspense and React.lazy based API in #42589, should work properly now

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
Development

Successfully merging a pull request may close this issue.

8 participants