Reputation: 6033
Since upgrading to React 16 I get this error message:
warning.js:33 Warning: Expected server HTML to contain a matching <div> in <body>.
What is generally causing this error message and how can it be fixed?
Upvotes: 78
Views: 159198
Reputation: 583
Check the source code of your app.
If the source code has 2 </body
then you added body element twice by mistake.
Find it in your code and replace the inner body
element to div
element.
Upvotes: 0
Reputation: 1464
The solution: Use incognito
Apparently, my case is that the extensions I have caused this. So the way I solve it is just go to Incognito mode where most of my extensions are disabled there. Adding this answer because none seem to try to answer directly.
Upvotes: 1
Reputation: 2565
If using Remix SSR hydration and you see an error like:
Warning: Expected server HTML to contain a matching <head> in <html>
there is a known issue where browser plugins can cause this issue (you can verify it's plugins by trying to load the page in Incognito mode).
See this Github issue: https://github.com/remix-run/indie-stack/issues/184
Apparently you can disable this warning/error by adding suppressHydrationWarning={true}
to your <html>
tag but this didn't work for me
This is also described in Remix's Gotchas: https://remix.run/docs/en/1.14.3/pages/gotchas#md-browser-extensions-injecting-code
This has been a frustrating and known issue for a long time and I have no idea why the Remix team has still not fixed this :(
Upvotes: 1
Reputation: 139
In my case I got an error when upgrading to Next.js 13, specifically when using Drawer
from @mui/material
. It seems switching to server side components is not easy.
return (
<Drawer
anchor="left"
onClose={onClose}
open={open}
PaperProps={{
sx: {
backgroundColor: 'neutral.900',
color: '#FFFFFF',
width: 280
}
}}
sx={{zIndex: (theme) => theme.zIndex.appBar + 100}}
// 'persistent' or 'permanent' throws error
variant="temporary"
>
{content}
</Drawer>
);
Upvotes: 1
Reputation: 1
The issue can be caused because the client and server mismatch during HMR updates
I resolved that way:
const renderMethod = !!module.hot ? ReactDOM.render : ReactDOM.hydrate
const renderMethod = !!module.hot ? ReactDOM.render : ReactDOM.hydrate
renderMethod(
<AppContainer>
<Comp />
</AppContainer>,
document.getElementById('root')
)
Upvotes: 0
Reputation: 51
Looks like you're trying to access a prop in a dom before is ready. You can use a structure like this:
{(variable) && sameVariable}
Upvotes: -1
Reputation: 5196
I got this using material UI by trying to do const searchParams = new URLSearchParams(process.browser ? window.location.search : '')
at the top of the react component in my NextJS app with material-ui SnackBar, I was able to remove the error by putting this in a useEffect
hook.
Entire component for reference:
export default function SnackBarMessage() {
const [requestLogin, setRequestLogin] = useState(false)
const handleClose = (event, reason) => {
if (reason === 'clickaway') {
return
}
setRequestLogin(false)
}
useEffect(() => {
// had to move into a useEffect hook
const searchParams = new URLSearchParams(process.browser ? window.location.search : '')
const hasRequestLogin = Boolean(searchParams.get('requestLogin'))
if (hasRequestLogin) {
setRequestLogin(true)
}
}, [])
return (
<>
{requestLogin && (
<Snackbar open={requestLogin} autoHideDuration={6000} onClose={handleClose}>
<Alert onClose={handleClose} severity='error' style={{ fontSize: '18px' }} elevation={6}>
Please Log Back In
</Alert>
</Snackbar>
)}
</>
)
}
Upvotes: 2
Reputation: 31
In my case i installed REACTFUL and it do a render so different by default install:
src/renderers/dom.js
ReactDOM.hydrate(
<App initialData={window.__R_DATA.initialData} />,
document.getElementById('root'),
);
src/renderers/server.js
const initialData = {
appName: 'Reactful',
};
return Promise.resolve({
initialData,
initialMarkup: ReactDOMServer.renderToString(
<App initialData={initialData} />,
),
pageData,
});
care with initialData!
i fix it changed dom.js like it, attention to initialData is important:
const renderMethod = module.hot ? ReactDOM.render : ReactDOM.hydrate;
const initialData = {
appName: 'Reactful',
};
renderMethod(
<App initialData={initialData} />,
document.getElementById('root'),
);
Upvotes: 0
Reputation: 1841
In my case it was because of using PersistGate
and react-loadable
.
if you using this libraries, you could use preloadAll instead of preloadReady
Upvotes: 0
Reputation: 13587
If you're using Server Side Rendering like NextJS, delete recent code and compare if you've tried to access a variable directly inside of Component scope where DOM is not guaranteed yet. For me, it was:
import { i18n } from 'i18n'
export default function SomeComponent() {
const initLanguage = i18n.language <---- causing error
return ...
}
If you need to access such properties, access it within useEffect
, so as to make sure that document
is already established by then. It is kinda equivalent to componentDidMount()
:
import { i18n } from 'i18n'
import { useEffect, useState } from 'react'
export default function SomeComponent() {
const [initlanguage, setInitLanguage] = useState('en')
useEffect(() => setInitLanguage(i18n.language), [])
return ...
}
Upvotes: 35
Reputation: 134
I'm assuming you are using ssr. The warning is about attempting to render before there is a window object. You need to hydrate.
ReactDOM.hydrate(<App />, document.getElementById("home"))
What I don't understand, is that the App component is being served static by express. Why is it trying to render before it is served? Bring on the comments.
Upvotes: -2
Reputation: 891
If your HTML code is like
<table>
<tr>
you can get this error.
To get around it, use the <tbody> tag like
<table>
<tbody>
<tr>
Don't forget to close the tag(s)!
Upvotes: 46
Reputation: 428
If you use ReactDOM.hydrate
to start web application, you will see this warning.
If your application does not use server-side rendering (ssr
), please use ReactDOM.render
to start.
Upvotes: 38
Reputation: 6033
This seems to be because of Browsersync inserting a script tag in the body on client side that does not exist on server side. Thus React fails to attach to the server render.
Upvotes: 3