I'm getting the following error using SSR
Warning: Expected server HTML to contain a matching <div> in <div>.
The issue is on the client when checking the browser width on component mount, and then setting the state of a component to render a mobile version of it instead.
But the server is defaulting the desktop version of the container as it is not aware of the browser width.
How do I deal with such a case? Can I somehow detect the browser width on the server and render the mobile container before sending to the client?
EDIT: For now I've decided to render the container when the component mounts. This way, both server and client side render nothing initially preventing this error.
I'm still open to a better solution
This will solve the issue.
// Fix: Expected server HTML to contain a matching <a> in
const renderMethod = module.hot ? ReactDOM.render : ReactDOM.hydrate;
renderMethod(
<BrowserRouter>
<RoutersController data={data} routes={routes} />
</BrowserRouter>,
document.getElementById('root')
);
The current accepted answer doesn’t play well with TypeScript. Here is what works for me.
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<link rel="shortcut icon" href="/favicon.ico" />
<meta name="viewport" content="width=device-width, initial-scale=1" />
</head>
<body>
<noscript>
You need to enable JavaScript to run this app.
</noscript>
<div id="root"></div>
</body>
</html>
import React from "react"
import { hydrate, render } from "react-dom"
import BrowserRouter from "./routers/Browser"
const root = document.getElementById("root")
var renderMethod
if (root && root.innerHTML !== "") {
renderMethod = hydrate
} else {
renderMethod = render
}
renderMethod(<BrowserRouter />, document.getElementById("root"))
My solution is to use a middleware like express-useragent to detect the browser user agent.
Then, in the server side, create a viewsize
like {width, height}
by the following rules
if (ua.isMobile) {
return {width: 360, height: 480}
}
if (ua.isDesktop) {
return {width: 768, height: 600}
}
return {width: 360, height: 480} // default, and for bot
Then, it is still somehow a responsive design in SSR.
HTTP Client Hints could help you with this.
Another interesting article regarding Client Hints.