Reputation: 641
I am converting my React app into Next app to take advantage of SSR. I am using Material ui 4 for styling.
I have implemented _app.js
and _document.js
file as per the Material ui documentation but the problem is when the page is loaded for the first time, material ui styles are not being applied but when I make some changes in my components then only all the styles appear.
I am posting this question only after referring this, this answers and other resources on internet
_app.js
import '@assets/fonts/global.css';
import React, {useState, useEffect} from "react";
import Layout from "@layout/Layout";
import Footer from "@layout/Footer/Footer";
import Header from "@layout/Header/Header";
//import Sidebar from "@layout/Sidebar/Sidebar";
//Material UI
import CssBaseline from "@material-ui/core/CssBaseline";
import theme from "@helper/theme/theme";
import {ThemeProvider as MuiThemeProvider} from "@material-ui/styles";
//Redux
import {wrapper} from "@store/store";
function MyApp({Component, pageProps}) {
React.useEffect(() => {
// Remove the server-side injected CSS.
const jssStyles = document.querySelector('#jss-server-side');
if (jssStyles) {
jssStyles.parentElement.removeChild(jssStyles);
}
}, []);
return (
<>
<MuiThemeProvider theme={theme}>
<CssBaseline/>
<Header/>
<Layout>
<Component {...pageProps} />
</Layout>
<Footer/>
</MuiThemeProvider>
</>
);
}
export default wrapper.withRedux(MyApp);
_document.js
import React from 'react';
import Document, {Html, Head, Main, NextScript} from 'next/document';
import {ServerStyleSheets} from '@material-ui/core/styles';
import theme from "@helper/theme/theme";
export default class MyDocument extends Document {
render() {
return (
<Html lang="en">
<Head>
<meta name="theme-color" content={theme.palette.primary.main} />
</Head>
<body>
<Main/>
<NextScript/>
</body>
</Html>
);
}
}
MyDocument.getInitialProps = async (ctx) => {
console.log('DOC Called');
// Render app and page and get the context of the page with collected side effects.
const sheets = new ServerStyleSheets();
const originalRenderPage = ctx.renderPage;
ctx.renderPage = () => originalRenderPage({
enhanceApp: (App) => (props) => sheets.collect(<App {...props} />),
});
const initialProps = await Document.getInitialProps(ctx);
return {
...initialProps,
// Styles fragment is rendered after the app and page rendering finish.
styles: [...React.Children.toArray(initialProps.styles), sheets.getStyleElement()],
};
};
Note: Even after using _app.js
and _document.js
file as per the Material ui documentation I'm still getting the following warning in console
next-dev.js?3515:25 Warning: Prop `className` did not match.
Upvotes: 3
Views: 3658
Reputation:
I had the same issue for days here are the things i did:
_document.js
and _app.js
and index.js
provided in material official example. Make sure to follow every detail provided in each of these files. they way things are imported, their folder structure, combination of theme and …SSR
for components such as footer or some other static data that didn't need SSR
by adding nossr
wrapper. I had breakpoints in my themes which caused to break css
in refresh so turning off SSR when not needed made components to fully load on client:import React from 'react';
import dynamic from 'next/dynamic';
const NoSSRWrapper = props => <React.Fragment>{props.children}</React.Fragment>;
export default dynamic(() => Promise.resolve(NoSSRWrapper), {
ssr: false,
});
import NoSSRWrapper from '../../components/NoSSRWrapper';
function func() {
return (
<NoSSRWrapper>
//your component
</NoSSRWrapper>
)
}
Also I suggest instead of wrapping your _app.js
with redux you use <Provider store={store}>
something like this(small details of your _app.js matters)
import store from '../utils/store';
return (
<Provider store={store}>
<ThemeProvider theme={theme}>
<Layout>
<Component {...pageProps} />
</Layout>
</ThemeProvider>
</Provider>
)
Upvotes: 1
Reputation: 812
Perhaps the style mismatch issue? The reactStrictMode
is turned on by default if using create-next-app
According to the following link here: https://github.com/mui/material-ui/issues/18018 Material UI v4 is not strict mode compatible so until then you can try disabling reactStrictMode or use Material UI v5.
// in next.config.js
module.exports = {
reactStrictMode: false
}
Apologies if I misunderstood anything!
Upvotes: 0