I recently migrated to nextjs. I'm using material v4 and next version 10.2
I've tried the official example in material ui site to prevent loading the raw html first by adding the _document.js
file
https://github.com/mui/material-ui/tree/v4.x/examples/nextjs
so far my problem still exists.
This is my _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 '../assets/theme';
class MyDocument extends Document {
render() {
return (
<Html lang="en">
<Head>
<meta name="theme-color" content={theme.palette.primary.main} />
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css?family=Lato:300,400,500,700&display=swap"
/>
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}
MyDocument.getInitialProps = async ctx => {
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: [
...React.Children.toArray(initialProps.styles),
sheets.getStyleElement(),
],
};
};
export default MyDocument;
This is my _app.js
import React from 'react';
import PropTypes from 'prop-types';
import Head from 'next/head';
import { ThemeProvider } from '@material-ui/core/styles';
import theme from '../assets/theme';
import withMui from '../components/withMui';
import store from '../utils/store';
import { makeStyles } from '@material-ui/core/styles';
import { Provider } from 'react-redux';
import Ribbon from '../components/RibbonComponent';
const useStyles = makeStyles(() => ({
'@global': {
'*::-webkit-scrollbar': {
width: '0.4em',
},
'*::-webkit-scrollbar-track': {
'-webkit-box-shadow': 'inset 0 0 6px rgba(0,0,0,0.00)',
},
'*::-webkit-scrollbar-thumb': {
backgroundColor: 'rgba(0,0,0,.1)',
},
},
appWrapper: {
width: '100%',
height: '100%',
display: 'flex',
flexDirection: 'column',
},
appContent: { flex: 1 },
}));
function MyApp(props) {
const { Component, pageProps } = props;
const classes = useStyles();
React.useEffect(() => {
// Remove the server-side injected CSS.
const jssStyles = document.querySelector('#jss-server-side');
if (jssStyles) {
jssStyles.parentElement.removeChild(jssStyles);
}
}, []);
return (
<React.Fragment>
<Head>
<title>Tisitano</title>
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css?family=Lato:300,400,500,700&display=swap"
/>
<meta
name="viewport"
content="minimum-scale=1, initial-scale=1, width=device-width"
/>
<script src="https://www.gstatic.com/firebasejs/5.5.3/firebase-app.js"></script>
<script src="https://www.gstatic.com/firebasejs/5.5.3/firebase-firestore.js"></script>
<script
strategy="afterInteractive"
dangerouslySetInnerHTML={{
__html: `myfacebookKeyAndrelatedHtml`,
}}
/>
</Head>
<ThemeProvider theme={theme}>
<Provider store={store}>
<Ribbon />
<div className={classes.appWrapper}>
<div className={classes.appContent}>
<Component {...pageProps} />
</div>
</div>
</Provider>
</ThemeProvider>
</React.Fragment>
);
}
MyApp.propTypes = {
Component: PropTypes.elementType.isRequired,
pageProps: PropTypes.object.isRequired,
};
export default withMui(MyApp);
And my index.js
import React from 'react';
import Home from './home';
import MainFooter from '../components/home/mainFooter';
function Index() {
return (
<>
<Home /> <MainFooter />
</>
);
}
export default Index;
My withMui.js file
import React, { Component } from 'react';
import { ThemeProvider } from '@material-ui/core/styles';
import { createTheme } from '@material-ui/core/styles';
import myTheme from '../assets/theme';
const muiTheme = myTheme;
export default function outputComponent(NextPage) {
class outputComponent extends Component {
constructor(props) {
super(props);
this.state = {
nav: '',
};
}
componentDidMount() {
this.setState(state => {
state.nav = navigator.userAgent;
return state;
});
}
static async getInitialProps(ctx) {
const { req } = ctx;
const userAgent = req ? req.headers['user-agent'] : this?.state?.nav;
let pageProps = {};
if (NextPage.getInitialProps) {
pageProps = await NextPage.getInitialProps(ctx);
}
return {
...pageProps,
userAgent,
};
}
render() {
let userAgent = this.props.userAgent;
return (
<ThemeProvider theme={createTheme({ userAgent, ...muiTheme })}>
<NextPage {...this.props} />
</ThemeProvider>
);
}
}
return outputComponent;
}
Here is what I tried so far:
I tried removing
withMui
file and still I saw the raw html. by the way withoutwithmui
file all my styles break.I tried mixing the
_document.js
with mywithMui
file to have them both on server side it didn't work.I also made sure that server restarts.
I even saw on a github link to add a dummy script(which was not convincing but I tried it)
<script>0</script>
but this didn't work either.I added
getInitialProps
to my _app.js.I tried removing the ribbon and wrapper divisions from _app.js and adding them to index file it didn't work.
I can not update my material or next version due to dependency conflict for now so if anyone knows any workaround on these versions please help me.