Go back

How to fix styled-components server mismatch error in Next.js

When you build Next.js apps or websites with Styled components, there's a huge possibility that you'll run into this error below. But, Next.js supports styled-components now

styled components server mismatch error

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.