When you build Next.js apps or websites with Styled components, there's a huge possibility that you'll run into this error below.
This error causes the styles you've written to break on initial render, but when you navigate to another route, it'll behave as normal.
Here's what the error message from the image above says;
Warning: Prop className did not match Server: "sc-dQmhJc bhtCIJ" Client: "sc-dmyDGi hdipVs"
This error came up because I'm using styled-components in a Next.js app, and by default, Next supports SSR — Server-side Rendering — by default.
This happens because when the server renders the component, it generates a different CSS class name than when the component is rendered on the client.
To fix this issue, we can take two routes
Use a custom document.js file
In older versions of Next.js you'd have to create this file — _document.js
— by yourself. But, in the latest version, the file can be found in the pages
directory already.
Here's what the content of the file looks like. You can copy it and do what you wish with it.
import Document, { Html, Head, Main, NextScript } from 'next/document'
import { ServerStyleSheet } from 'styled-components'
function MyDocument() {
return (
<Html>
<Head />
<body>
<Main />
<NextScript />
</body>
</Html>
)
}
MyDocument.getInitialProps = async (ctx) => {
const sheet = new ServerStyleSheet()
const originalRenderPage = ctx.renderPage
try {
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: (App) => (props) => sheet.collectStyles(<App {...props} />),
})
const initialProps = await Document.getInitialProps(ctx)
return {
...initialProps,
styles: (
<>
{initialProps.styles}
{sheet.getStyleElement()}
</>
),
}
} finally {
sheet.seal()
}
}
export default MyDocument
The snippet above alone would stop your layouts from breaking on initial render. But the error in the image at the beginning of this article would persist when you open DevTools.
using babel-plugin-styled-components
This plugin ensures that the class names generated on the server and client are the same. You can set it up by installing the plugin
npm install --save-dev babel-plugin-styled-components
Next, create a .babelrc
file in the root of your project and add the following to the config file, and restart your server.
{
"presets": ["next/babel"],
"plugins": [
[
"styled-components",
{
"ssr": true
}
]
]
}
With these changes, the class names generated on the server and client should now match, and you would no longer see the warning message in the DevTools console.