remix: React 18 : Hydration failed because the initial UI does not match what was rendered on the server.
What version of Remix are you using?
1.3.4
Steps to Reproduce
Update https://github.com/remix-run/indie-stack/tree/main
- react: 18.0.0
- react-dom: 18.0.0
Update entry.client.tsx :
import { hydrateRoot } from "react-dom/client";
import { RemixBrowser } from "remix";
hydrateRoot(document, <RemixBrowser />);
Run dev with NODE_ENV=production
Expected Behavior
No error
Actual Behavior
White screen with errors :
Uncaught Error: Hydration failed because the initial UI does not match what was rendered on the server.
at throwOnHydrationMismatch (:3000/build/entry.client-K3EESZRH.js:10325:17)
at tryToClaimNextHydratableInstance (:3000/build/entry.client-K3EESZRH.js:10335:15)
at updateHostComponent$1 (:3000/build/entry.client-K3EESZRH.js:14601:13)
at beginWork (:3000/build/entry.client-K3EESZRH.js:15679:22)
at HTMLUnknownElement.callCallback2 (:3000/build/entry.client-K3EESZRH.js:3453:22)
at Object.invokeGuardedCallbackDev (:3000/build/entry.client-K3EESZRH.js:3478:24)
at invokeGuardedCallback (:3000/build/entry.client-K3EESZRH.js:3512:39)
at beginWork$1 (:3000/build/entry.client-K3EESZRH.js:18903:15)
at performUnitOfWork (:3000/build/entry.client-K3EESZRH.js:18367:20)
at workLoopSync (:3000/build/entry.client-K3EESZRH.js:18307:13)
Warning: An error occurred during hydration. The server HTML was replaced with client content in <#document>.
Uncaught DOMException: Failed to execute 'appendChild' on 'Node': Only one element on document allowed.
at appendChildToContainer (http://192.168.1.17:3000/build/entry.client-K3EESZRH.js:7946:24)
at insertOrAppendPlacementNodeIntoContainer (http://192.168.1.17:3000/build/entry.client-K3EESZRH.js:16695:15)
at insertOrAppendPlacementNodeIntoContainer (http://192.168.1.17:3000/build/entry.client-K3EESZRH.js:16702:15)
at insertOrAppendPlacementNodeIntoContainer (http://192.168.1.17:3000/build/entry.client-K3EESZRH.js:16702:15)
at insertOrAppendPlacementNodeIntoContainer (http://192.168.1.17:3000/build/entry.client-K3EESZRH.js:16702:15)
at insertOrAppendPlacementNodeIntoContainer (http://192.168.1.17:3000/build/entry.client-K3EESZRH.js:16702:15)
at insertOrAppendPlacementNodeIntoContainer (http://192.168.1.17:3000/build/entry.client-K3EESZRH.js:16702:15)
at insertOrAppendPlacementNodeIntoContainer (http://192.168.1.17:3000/build/entry.client-K3EESZRH.js:16702:15)
at insertOrAppendPlacementNodeIntoContainer (http://192.168.1.17:3000/build/entry.client-K3EESZRH.js:16702:15)
at insertOrAppendPlacementNodeIntoContainer (http://192.168.1.17:3000/build/entry.client-K3EESZRH.js:16702:15)```
About this issue
- Original URL
- State: closed
- Created 2 years ago
- Reactions: 8
- Comments: 31 (11 by maintainers)
Links to this issue
Commits related to this issue
- Revert to react 17 for now. Tracking in: https://github.com/remix-run/remix/issues/2570 https://github.com/remix-run/remix/issues/2947 — committed to DAlperin/dov.dev-remix by DAlperin 2 years ago
This issue still happens with react 18.2.0 as I init the project with the indie stack.
Any update here?
@rphlmr I think this issue should be reopened. I deployed my first production remix app and have gotten consistent reports from users who have any extension that mutated the DOM (many many of them) I’m going to revert to react 17 tomorrow, but this issue should be considered ‘breaking’.
If you’d prefer, I can open another issue.
Something that I’ve been wondering about:
I don’t think it’s a good idea to hydrate the entire document because for chrome extensions that modify the DOM (e.g. Apollo Client DevTools, LastPass, Dark Reader), they will add / change the DOM significantly by injecting CSS / JS.
In my case
Apollo Client Devtoolswas causing the app to crash after upgrade to React v18, because it was injecting a script tag on client side.Who have this problem could try running in incognito mode in order to exclude browser extensions.
I have the same problem with
cypressended up doing this workaround“Dark Reader” extension also triggers this error. Of course, disabling extensions isn’t a solution. I can’t ask visitors to disable all extensions to view my site. @MichaelDeBoey could you reopen this issue?
I just went back to using
hydratefromreact-dominstead of the newhydrateRoot, the fix suggested by @danestves for cypress, only works if you are running cypress locally.For running it against deployed staging environments etc, it will not work.
Awaiting a fix in the meantime
@rphlmr Could we re-open this? Multiple people have faced this issue in the discord. I think the problem lies in upgrading an existing app but I have no idea why that would cause problems. I am fairly confident caching isn’t the issue. The problem persists across multiple browsers and private browsing .
I have a Remix stack following indie stack and my cypress runs fine (when it’s not timed out 🤭) on GitHub action.
I just have to add this, somewhere in
cypress/support:(source)
But, even with entry files like the indie stack, you’ll still have an error in the console in prod (not breaking things but disgracious)
Cross linking this https://github.com/facebook/react/issues/22833
@rphlmr figured it out!
remix-themesseemed to be playing weirdly with the new hydration in some edge cases. (I think the useTheme hook was returning conflicted values on the client and the server). I’ll open up a issue over there to track. Thank you for your help!@rphlmr I just tried
rm -rf tmp .cache build && npm run devand the problem persists. Any ideas?Also I am not using cypress, so the problem must be related but different
This issue remains.
import { hydrate } from 'react-dom'Is working for now but not ideal since it only allows you to make use of react v17 features.
Happened to me due to Yoroi And agree with @ostwilkens expecting user (and developers) to disable browser extensions is not a solution
@hrgui yea, though I love that Remix gives us the full control, maybe hydrating
document.head&document.bodyinstead might help? Well Yoroi is injecting before<head>not sure what others do, if they inject into<head>oder<body>same issue would happen I guess? 🤔@DAlperin Yes I can 😉 I reproduce if I
npm run devafter a cypress run. But if i clean build folder and re run dev, no more problems 🤷♂️