Text content did not match. Warning in React 16
Solution 1
For those discovering this error because your client and server purposefully render different content (like the server rendering a dark theme which gets replaced with the user preference on load), use suppressHydrationWarning
to suppress the error.
For example:
<div suppressHydrationWarning>Ignore this</div>
Solution 2
The problem here is that your server-side application does not reflect code changes. To do that you have to configure your express app as a webpack entry.
Briefly, you need 2 webpack configurations one for server and another for client code. The server one will look something like this
module.exports = {
entry: {
server: './server.js',
},
output: {
path: path.join(__dirname, 'dist'),
publicPath: '/',
filename: '[name].js'
},
target: 'node',
node: {
// Need this when working with express, otherwise the build fails
__dirname: false, // if you don't put this is, __dirname
__filename: false, // and __filename return blank or /
},
externals: [nodeExternals()], // Need this to avoid error when working with Express
module: {
rules: [
{
// Transpiles ES6-8 into ES5
test: /\.js$/,
exclude: /node_modules/,
use: {
loader: "babel-loader"
}
},
{
// Loads the javacript into html template provided.
// Entry point is set below in HtmlWebPackPlugin in Plugins
test: /\.html$/,
use: [{loader: "html-loader"}]
}
]
},
plugins: [
new HtmlWebPackPlugin({
template: "./index.html",
filename: "./index.html",
excludeChunks: [ 'server' ]
})
]
}
Here is a nice article explaining how to do that in details
Pavel Perevezencev
Updated on April 30, 2021Comments
-
Pavel Perevezencev about 3 years
I trying to build ReactJs application with server side rendering My entry points for client and server:
const store = createStore(window.__INITIAL_STATE__); hydrate( <Provider store={store}> <BrowserRouter>{renderRoutes(routes)}</BrowserRouter> </Provider>, document.querySelector('#root') );
const app = express(); if (isDev) { const webpack = require('webpack'); const webpackDevMiddleware = require('webpack-dev-middleware'); const config = require('../../webpack.config.js'); const compiler = webpack(config); app.use(express.static('/public')); app.use( webpackDevMiddleware(compiler, { publicPath: config.output.publicPath, stats: 'errors-only', }) ); } app.get('*', (req, res) => { const helmet = Helmet.renderStatic(); const htmlAttrs = helmet.htmlAttributes.toComponent(); const bodyAttrs = helmet.bodyAttributes.toComponent(); const context = {}; const data = {}; res.set('content-type', 'text/html'); res.send( '<!DOCTYPE html>' + renderToString( <html {...htmlAttrs}> <head> {helmet.title.toComponent()} {helmet.meta.toComponent()} {helmet.link.toComponent()} </head> <body {...bodyAttrs}> <div id="root"> <StaticRouter location={req.url} context={context}> {renderRoutes(routes)} </StaticRouter> </div> <script dangerouslySetInnerHTML={{ __html: `window.__INITIAL_STATE__ = ${JSON.stringify(data)}`, }} /> <script src="/public/vendor.js" /> <script src="/public/app.js" /> </body> </html> ) ); });
And component:
home.jsx
import React, { Component } from 'react'; class Home extends Component { render() { return <div>home</div>; } } export default Home;
When I change in my component
Home
and refresh browser page I get this error:Warning: Text content did not match. Server: "home" Client: "home1"
Its ok because server render old version of my code. How to reload the code on the server so that the client and server versions are equal?
-
locopump almost 3 yearsthanks this help me, it was very simple =D, Thanks :D