next.js: Next.js 13.4.10 breaks useSyncExerternalStore
Verify canary release
- I verified that the issue exists in the latest Next.js canary release
Provide environment information
Operating System:
Platform: darwin
Arch: arm64
Version: Darwin Kernel Version 22.4.0: Mon Mar 6 21:01:02 PST 2023; root:xnu-8796.101.5~3/RELEASE_ARM64_T8112
Binaries:
Node: 18.16.0
npm: 9.5.1
Yarn: 3.5.0
pnpm: 7.32.1
Relevant packages:
next: 13.4.10
react: 18.2.0
react-dom: 18.2.0
typescript: 5.1.3
(I downgraded after this bug came up)
Which area(s) of Next.js are affected? (leave empty if unsure)
No response
Link to the code that reproduces this issue or a replay of the bug
https://github.com/tamagui/tamagui/tree/72b28addf5969b6cc3f0953f8ab7ea7a1d05271c
To Reproduce
Can reproduce loading this using Chrome responsive mode iPhone X:
https://site-iqj7d8h5p-tamagui.vercel.app
In the repo checkout 72b28addf5969b6cc3f0953f8ab7ea7a1d05271c, yarn
and yarn site
and then load the homepage on mobile device.
Describe the Bug
main-79f22335469cfa5b.js:1 TypeError: Cannot read properties of null (reading 'getSnapshot')
at Object.aP [as useSyncExternalStore] (framework-e5b12c291073d220.js:9:63102)
at n.useSyncExternalStore (framework-e5b12c291073d220.js:25:6223)
at y (_app-17f1cfb0d0a82165.js:12:7258)
at B (80-fe61b202f42fb298.js:1:5781)
at V.Anchor (80-fe61b202f42fb298.js:1:4923)
at ab (framework-e5b12c291073d220.js:9:60869)
at ud (framework-e5b12c291073d220.js:9:72751)
at i (framework-e5b12c291073d220.js:9:120306)
at oO (framework-e5b12c291073d220.js:9:99058)
at framework-e5b12c291073d220.js:9:98925
at oF (framework-e5b12c291073d220.js:9:98932)
at ox (framework-e5b12c291073d220.js:9:95684)
at oC (framework-e5b12c291073d220.js:9:96073)
at r4 (framework-e5b12c291073d220.js:9:44769)
at framework-e5b12c291073d220.js:9:111585
at oI (framework-e5b12c291073d220.js:9:111591)
at oS (framework-e5b12c291073d220.js:9:94961)
at x (framework-e5b12c291073d220.js:33:1364)
at MessagePort.T (framework-e5b12c291073d220.js:33:1894)
Expected Behavior
No bug
Which browser are you using? (if relevant)
No response
How are you deploying your application? (if relevant)
No response
About this issue
- Original URL
- State: closed
- Created a year ago
- Reactions: 35
- Comments: 15 (7 by maintainers)
I’m wondering about why a custom hook using
useSyncExternalStore
may not be called on the server side. The third parameter, thegetServerSnapshot
function, seems to support SSR based on a specific snapshotValue(== fallbackValue.)When a directive is added, the following error occurs.
Happens in Next
14.1.0
In my opinion, I think this hook should be able to run on both the server and client sides.
Happens in Next 14. If
useSyncExternalStore
has a third argument to get the server snapshot, then why does it error while being called on the server-side?Although React allows useSyncExternalStore to be used server-side, it’s important to note that Next.js currently does not provide support for this feature. While React offers this capability, Next.js lacks compatibility with useSyncExternalStore on the server-side. However, there is a case to be made for incorporating support for this feature into Next.js for a more seamless server-side rendering experience. We have use cases for it in our code base.
Thanks @0xBigBoss. I can’t say it followed exactly https://github.com/vercel/next.js/issues/52707#issuecomment-1686215955, as I still used much time to remove a bunch of unrelated code/dependencies, etc. Ideally, a minimal reproduction is much more minimal. But I was at least able to start it up.
My conclusion is that it’s related to https://github.com/tamagui/tamagui/blob/master/packages/next-plugin/src/withTamagui.ts which makes a bunch of modifications to the
webpack
config, which is not covered by semver, as documented https://nextjs.org/docs/app/api-reference/next-config-js/webpackIt would be very valuable to see a reproduction that does not modify Next.js internals via the
webpack
config to verify whether it’s an expected bug or not.Hey Tim, sorry try running yarn site:prod. It’s only the prod release. And then load the site in a small viewport I usually just enable iPhone emulation in chrome.