I'm using reactstrap (bootstrap) together with react-responsive for my site's responsive layout.
There is no problem when I'm using reactstrap alone.
However, when I mix react-responsive into the pages to show certain components only at certain screen breakpoints, I'm getting the following error in the browser console:
main.js:4530 Warning: Expected server HTML to contain a matching <div> in <div>.
The error should not be showing up in the browser console.
An error main.js:4530 Warning: Expected server HTML to contain a matching <div> in <div>.
will appear in the console when ever a page is refreshed.
I'm using reactstrap (bootstrap) together with react-responsive for my site's responsive layout.
There is no problem when I'm using reactstrap alone.
However, when I mix react-responsive into the pages to show certain components only at certain screen breakpoints, I'm getting the following error in the browser's console:
main.js:4530 Warning: Expected server HTML to contain a matching <div> in <div>.
Removing the responsive component will get rid of this error message too.
Although I'm not certainly sure what's the cause, I'm suspecting this has to do with the server side rendering. The mobile component was probably rendered dynamically on client but not on server side.
Is there anything I can do to fix this error? Any impact if the error is left unresolved?
| Tech | Version |
|---------|---------|
| next | 5.0.0 |
| node | 6.9.1 |
| OS | Win 10 |
| browser | Chrome |
| etc | |
this is probably due to the responsive component rendering on the server side with a static width (you can't know the client viewport on the server ofcourse). The warning impacts the time before your app becomes interactive, since React has to repaint certain components. I hope that answers your question. Going to close this as it's unrelated to Next.
@timneutkens Just wondering, will this actually impact nextjs' server rendering in any ways if this error is left as it is (unfixed)?
It won't effect SSR, that's why it's a warning coming from React, but you lose a few benefits of SSR, mainly that when the content is hydrated by React it doesn't have to re-render.
You can run that component with NO SSR. Problem will be fixed!
I have this issue too, and it effects production build. I'm using react-responsive, and I decide which layout to use by detecting window width(specifically by react-responsive's MediaQuery). But when it's SSR, I won't get device width, so it's always one layout being shown. Strange thing here is React doesn't re-render, so I'm getting the wrong layout & styles.
anyway I can fix this issue? @timneutkens
I guess I can run certain component without SSR. How can I achieve this? @xmanzero
You could use next/dynamic
with ssr: false
Strange thing here is React doesn't re-render, so I'm getting the wrong layout & styles.
That is an issue I am now dealing with after porting a large scale project from Electrode to NextJS. It used to rerender the layout on the client, but now the width stays wrong (react-responsive is not updating), and although render method is called on the client, the React JS output is not affected.
Not sure how to solve it.
You could use
next/dynamic
withssr: false
@timneutkens this does not work
@superical did you solve this?
Artsy has a good solution for responsive SSR rendering via @artsy/fresnel. Here's an example that works with Next, and a blog post.
@damassi Have you worked with artsy solution? It almost feels like going full circle having to implement media-breakpoints again ...
Hi @FBosler - yup, I work there. Did you have any questions? Fresnel solves a very specific problem, and that is how does one handle SSR rendering with responsive layouts (although it also works very nicely with client-side only code). The API is declarative via react components, so there's nothing that one needs to implement in CSS, etc; not sure what you mean?
@damassi Ahhh nice, I actually came across the blog before asking the question. It's well written. My question was only around adoption and stability of the solution. I am always a bit hesitant when a library does not seem to be mainstream yet.
What I meant by full circle, but this could also be due to some misconception on my side, is that it seems like by implementing these media breakpoints I wouldn't really be able to use say bootstraps gridsystem, would I?
You certainly could -- it's just a matter of passing in the same set of breakpoints that bootstrap's grid uses, like so:
const { MediaContextProvider, Media } = createMedia({
breakpoints: {
sm: 0,
md: 768,
lg: 1024,
xl: 1192,
},
})
And then from there can mix and match as needed
const App = () => (
<MediaContextProvider>
<Media at="sm">
<div className='col-12'>
<MobileApp />
</div>
</Media>
<Media at="md">
<TabletApp />
</Media>
<Media greaterThanOrEqual="lg">
<DesktopApp />
</Media>
</MediaContextProvider>
)
@damassi
I was doing POC with @artsy/fresnel, for this problem.
found you ship the whole page over the wire with all breakpoints, it's just not the HTML but javascript is also shipping.
this is the issue link - https://github.com/artsy/fresnel/issues/156
to detect device width on the server-side, I am using CloudFront header
https://aws.amazon.com/blogs/aws/enhanced-cloudfront-customization/
cloudfront-is-tablet-viewer
cloudfront-is-mobile-viewer
I think the best solution to this problem is while SSG process we can pass breakpoints to generate static pages for the required screen sizes and use the CloudFront header to detect and ship the correct screen size page
Most helpful comment
Artsy has a good solution for responsive SSR rendering via @artsy/fresnel. Here's an example that works with Next, and a blog post.