-
Notifications
You must be signed in to change notification settings - Fork 26.8k
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
[breaking] 13.0.7 next/dynamic
: fallback
no longer rendered for client side async component using suspense: true
and <Suspense fallback={...}>
#45116
Comments
This issue is introduced in Next.js version 13.0.7, specifically in the functionality of asynchronous components that use the "suspense: true" attribute and the component. The fallback functionality is no longer being rendered because next/dynamic is now using its own block with the fallback set from the load option. This change broke backwards compatibility and is not mentioned in the release notes. The problem can be solved by changing the code to use the loading option with next/dynamic, or by using React.lazy directly if the Loading component needs to receive properties from the render stream. Here is an example of how to use the load option with next/dynamic to solve this problem: import dynamic from 'next/dynamic'
const MyAsync = dynamic(() => import("./MyAsync"), {
loading: () => <p>Loading...</p>,
});
const Component = () => (
<div>
<MyAsync />
</div>
);
export default Component In this example, the dynamic component "MyAsync" is imported using next/dynamic, and a loading component is set using the "loading" option. This way, while the "MyAsync" component is loading, it will show the load component instead. It is important to mention that if you want to continue using the fallback functionality of React.Suspense, you will need to use the React.lazy function. |
## Issue To address the problem that we introduced in 13.0.7 (#42589) where we thought we could use same implementation `next/dynamic` for both `pages/` and `app/` directory. But it turns out it leads to many problems, such as: * SSR preloading could miss the content, especially with nested dynamic calls * Closes #45213 * Introducing suspense boundary into `next/dynamic` with extra wrapped `<Suspense>` outside will lead to content is not resolevd during SSR * Related #45151 * Closes #45099 * Unexpected hydration errors for suspense boundaries. Though react removed this error but the 18.3 is not out yet. * Closes #44083 * Closes #45246 ## Solution Separate the dynamic implementation for `app/` dir and `pages/`. For `app/` dir we can encourage users to: * Directly use `React.lazy` + `Suspense` for SSR'd content, and `next/dynamic` * For non SSR components since it requires some internal integeration with next.js. For `pages/` dir we still keep the original implementation If you want to use `<Suspense>` with dynamic `fallback` value, use `React.lazy` + `Suspense` directly instead of picking up `next/dynamic` * Closes #45116 This will solve various issue before react 18.3 is out and let users still progressively upgrade to new versions of next.js. ## Bug Fix - [x] Related issues linked using `fixes #number` - [x] Integration tests added - [ ] Errors have a helpful link attached, see [`contributing.md`](https://github.com/vercel/next.js/blob/canary/contributing.md)
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. |
Verify canary release
Provide environment information
next: 13.0.7
react: 18.2.0
Which area(s) of Next.js are affected? (leave empty if unsure)
Dynamic imports (next/dynamic)
Link to the code that reproduces this issue
https://codesandbox.io/p/sandbox/dynamic-with-v13-0-7-1bkhgf
To Reproduce
You may need to throttle your network speed to see the fallback loading/not loading and click reload on the sandbox browser
13.0.6 works: https://codesandbox.io/p/sandbox/dynamic-with-v13-0-6-h2iq5i
13.0.7 broken: https://codesandbox.io/p/sandbox/dynamic-with-v13-0-7-1bkhgf
13.1.4-canary.0 still broken: https://codesandbox.io/p/sandbox/dynamic-with-canary-dd9bqz
Describe the Bug
#42589 introduced a breaking change for client side only async components using
suspense: true
and<Suspense fallback={...}>
. Thefallback
is no longer rendered since nownext/dynamic
renders its own<Suspense>
block withfallback
set from theloading
option.For this example the
fallback
is no longer rendered:To get it to work again I'm required to change my code to use
loading
option withnext/dynamic
, or useReact.lazy
directly if myLoading
component needs to receive props from the render flow.Visual example
13.0.6 with
fallback
renderedScreen.Recording.2023-01-20.at.1.32.25.PM.mov
13.0.7
fallback
is not renderedScreen.Recording.2023-01-20.at.1.31.03.PM.mov
Expected Behavior
I wouldn't expect there to be breaking changes when upgrading a patch version. Breaking changes should be called out in the release notes. I can work around this issue by making code changes, but ideally
next/dynamic
should detect ifsuspense: true
option is set and revert to the old behavior in that case to maintain backwards compatibility.Which browser are you using? (if relevant)
No response
How are you deploying your application? (if relevant)
No response
The text was updated successfully, but these errors were encountered: