0

I have a Next.js project that uses Material UI, if I run the server and make changes, hot reloading works fine but if I manually refresh the page all the styles mess up and I get the Warning: Prop className did not match. Server: "MuiTypography-root MuiLink...

This issue has been mentioned in Next.js issues on Github, and none of the proposed solutions work for me.

Steve
  • 11,596
  • 7
  • 39
  • 53
Saber
  • 5,150
  • 4
  • 31
  • 43

1 Answers1

1

It's a problem with Next.js and @material-ui. The problem has something to do with SSR (Server Side Rendering) so you have to cancel it and remove the server side files.

step 1: create _document.js under pages folder

step 2: add this to the documents file

import { ServerStyleSheets } from '@material-ui/core';
import Document, { Head, Html, NextScript, Main } from 'next/document';
import React from 'react';

export default class MyDocument extends Document {
  render() {
    return (
      <Html lang="en">
        <Head></Head>
        <body>
          <Main></Main>
          <NextScript></NextScript>
        </body>
      </Html>
    );
  }
}

MyDocument.getInitialProps = async (ctx) => {
  const sheets = new ServerStyleSheets();
  const originalRenderPage = ctx.renderPage;
  ctx.renderPage = () => {
    return originalRenderPage({
      enchanceApp: (App) => (props) => sheets.collect(<App {...props} />),
    });
  };
  const initialProps = await Document.getInitialProps(ctx);
  return {
    ...initialProps,
    styles: [
      ...React.Children.toArray(initialProps.styles),
      sheets.getStyleElement(),
    ],
  };
};

step 3: inside the _app.js add this inside the main function component

  useEffect(() => {
    const jssStyles = document.querySelector('#jss-server-side');
    if (jssStyles) jssStyles.parentElement.removeChild(jssStyles);
  }, []);

restart the Next.js app and you're done

Steve
  • 11,596
  • 7
  • 39
  • 53