We are using NextJS and Material-UI for our site, and upon loading the pages, it gives a FOUC. I've narrowed the problem down to the fact that the JS loads faster than the .css file, so I was wondering if there was a way to preload the .css file? All of our pages use the same .css file which is located under /pages/styles.css
Here is /pages/_app.js if that's any help:
// pages/_app.js
import { Provider } from 'next-auth/client'
import { createMuiTheme } from '@material-ui/core/styles';
import { ThemeProvider } from '@material-ui/styles';
import styles from './styles.css'
import Layout from '../components/layout'
import Head from 'next/head'
const theme = createMuiTheme({
palette: {
primary: {
main: "#2196f3", // blue
},
secondary: {
main: "#d3d3d3", // gray
},
},
});
export default function _App ({ Component, pageProps }) {
return (
<ThemeProvider theme={theme}>
<Provider options={{ clientMaxAge: 0, keepAlive: 0 }} session={pageProps.session}>
<Layout>
{/* Head */}
<Head>
<title>Kevin Support</title>
<link rel="icon" href="/static/favicon.png"/>
</Head>
{/* Page */}
<Component {...pageProps} />
</Layout>
</Provider>
</ThemeProvider>
)
}
Perhaps styles weren't applied on the server-side. Try to add _document.js from Material-UI's Next.js example. Adjust it to your needs.
// pages/_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 '../src/theme';
export default class MyDocument extends Document {
render() {
return (
<Html lang="en">
<Head>
{/* PWA primary color */}
<meta name="theme-color" content={theme.palette.primary.main} />
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"
/>
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
}
// `getInitialProps` belongs to `_document` (instead of `_app`),
// it's compatible with server-side generation (SSG).
MyDocument.getInitialProps = async (ctx) => {
// Resolution order
//
// On the server:
// 1. app.getInitialProps
// 2. page.getInitialProps
// 3. document.getInitialProps
// 4. app.render
// 5. page.render
// 6. document.render
//
// On the server with error:
// 1. document.getInitialProps
// 2. app.render
// 3. page.render
// 4. document.render
//
// On the client
// 1. app.getInitialProps
// 2. page.getInitialProps
// 3. app.render
// 4. page.render
// 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()],
};
};
Also, you can try to remove server-side injected CSS in the _app.js like so (see example):
React.useEffect(() => {
// Remove the server-side injected CSS.
const jssStyles = document.querySelector('#jss-server-side');
if (jssStyles) {
jssStyles.parentElement.removeChild(jssStyles);
}
}, []);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With