Skip to content

[breaking] 13.0.7 next/dynamic: fallback no longer rendered for client side async component using suspense: true and <Suspense fallback={...}> #45116

Description

@cvbuelow

Verify canary release

  • I verified that the issue exists in the latest Next.js 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={...}>. The fallback is no longer rendered since now next/dynamic renders its own <Suspense> block with fallback set from the loading option.

For this example the fallback is no longer rendered:

const MyAsync = dynamic(() => import("./MyAsync"), { suspense: true });
const Loading = () => 'Loading...'

const Component = () => (
  <Suspense fallback={<Loading />}>
    <MyAsync />
  </Suspense>
)

To get it to work again I'm required to change my code to use loading option with next/dynamic, or use React.lazy directly if my Loading component needs to receive props from the render flow.

Visual example

13.0.6 with fallback rendered

Screen.Recording.2023-01-20.at.1.32.25.PM.mov

13.0.7 fallback is not rendered

Screen.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 if suspense: 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

Metadata

Metadata

Assignees

No one assigned

    Labels

    Lazy LoadingRelated to Next.js Lazy Loading (e.g., next/dynamic or React.lazy).linear: nextConfirmed issue that is tracked by the Next.js team.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions