9

I've found the solution from the doc of materialui (https://material-ui.com/guides/server-rendering/) but I still don't know the reason.

  1. Why the style works in the first time rendering but disappear in the second time? I know SSR will generate the html template with css to the client side in each request so the style should still work because it is injected in the html template.

  2. In the document, it mentioned that "On the client side, the CSS will be injected a second time before removing the server-side injected CSS." However, I don't know why it needs to be removed. CSS is injected in the html template in each request so it will not cause any crash in my thinking and why the style will not disappear after removed the injected css.

Michael Tsai
  • 751
  • 2
  • 11
  • 21

3 Answers3

3

If you using styled-components then do the following and you are good to go!

Step 1: npm install --save-dev babel-plugin-styled-components

Step 2: Create a file [.babelrc] in the root directory of next project

Step 3: Paste Following Code to .babelrc File:-

         {
             "presets": ["next/babel"],
             "plugins": [["styled-components", { "ssr": true }]]
         }

Step 4: Restart the next server

1

I added this to my next.config.js and suddenly it works. I don't remember exactly why it works though.

/** @type {import('next').NextConfig} */
const nextConfig = {
    reactStrictMode: true,
    compiler: {
    // https://nextjs.org/docs/advanced-features/compiler
        // see https://styled-components.com/docs/tooling#babel-plugin for more info on the options.
        styledComponents: true,
    },
};

module.exports = nextConfig;
0

in _app.js

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

  return <Component {...pageProps} />
};

then open _document.js inside the pages folder :

import React from 'react';
import { ServerStyleSheets } from "@mui/styles";
import Document, { Html, Main, NextScript, Head } from "next/document";



export default class MyDocument extends Document{

    render(){

        return(
            <Html lang="en">
                <Head></Head>
                <body>
                    <Main/>
                    <NextScript/>
                </body>
            </Html>
        )
    }
}


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