Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Next.Js React app with styled components. Warning: Prop `className` did not match. Server: "x" Client: "y"

In my NextJS React app when i change something in the code, the HMR works and shows the correct update but if I refresh the page, this error comes up again. This happens on dev mode. Noticed where are a lot of topics with this error, tried all day different configuration setups with no effort.

Please help me to get rid of the error.

Error:

Warning: Prop className did not match. Server: "sc-cBoprd hjrjKw" Client: "sc-iCoHVE daxLeG"

Using "babel-plugin-styled-components": "1.11.1"

Files that can be related to the issue:

_App.tsx

function MyApp({ Component, pageProps, mainController }) {
  return (
    <ConfigurationProvider configuration={configuration}>
        <ThemeProvider theme={mainController.getTheme()}>
          <Normalize />
          <Font />
          <Component {...pageProps} controller={mainController} />
        </ThemeProvider>
    </ConfigurationProvider>
  );
}

export default appControllerContext(MyApp);

_document.tsx

import Document from 'next/document'
import { ServerStyleSheet } from 'styled-components'

export default class MyDocument extends Document {
  static async getInitialProps(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()
    }
  }
}

.babelrc

{
  "presets": [
    "next/babel"
  ],
  "plugins": [
    [
      "babel-plugin-styled-components",
      {
        "ssr": true,
        "displayName": true,
        "preprocess": false
      }
    ]
  ]
}
like image 497
Paulius Rimgaila Avatar asked Oct 13 '20 13:10

Paulius Rimgaila


2 Answers

This error means that something on the server is different from the Client. This can happen if the client does a re-render.

Styled Components use a random id on React elements, and when these elements get re-rendered they get a new random id on the client.

So the solution here is to get the styling exclusively from the server.

from the docs:

Basically you need to add a custom pages/_document.js (if you don't have one). Then copy the logic for styled-components to inject the server side rendered styles into the <head>

To solve this issue is you need something like this in your Document component:

export default class MyDocument extends Document {
  static getInitialProps({ renderPage }) {
    const sheet = new ServerStyleSheet();
    const page = renderPage((App) => (props) =>
      sheet.collectStyles(<App {...props} />)
    );
    const styleTags = sheet.getStyleElement();
    return { ...page, styleTags };
  }
  ...
  render() { ..}
}

The final step (if the error persists) is to delete the cache: delete the .next folder and restart the server

The full example code from Next documentation is here

like image 110
Bar Horing Amir Avatar answered Sep 18 '22 20:09

Bar Horing Amir


Finally the one and only solution that worked was to rename .babelrc.json to babel.config.json. If someone still getting this error here i leave reference how to fix that solution

like image 36
Paulius Rimgaila Avatar answered Sep 17 '22 20:09

Paulius Rimgaila