I was following this github template: https://github.com/mui/material-ui/tree/master/examples/material-next
This is my website: https://ai-content-detector.online/
Its not able to load mui styles on first render. I have used emotion cache and server as mentioned in the above template.
_document.js
import Document, { Html, Head, Main, NextScript } from "next/document";
import Script from "next/script";
import React from "react";
import createEmotionServer from "@emotion/server/create-instance";
import createEmotionCache from "../createEmotionCache";
import PropTypes from "prop-types";
export default function MyDocument(props) {
const { emotionStyleTags } = props;
return (
<Html lang="en">
<Head>
<link rel="canonical" href="https://ai-content-detector.online" />
<meta charSet="utf-8" />
<link rel="icon" href="/favicon.ico" />
<meta name="theme-color" content="#000000" />
<meta
name="description"
content="This tool is a one stop destination for detecting AI-generated text. Lets fight back against AI-generated plagiarism."
/>
<meta property="og:image" content="/favicon.ico" />
<meta name="emotion-insertion-point" content="" />
{emotionStyleTags}
</Head>
<body>
<Main />
<NextScript />
</body>
</Html>
);
}
MyDocument.getInitialProps = async (ctx) => {
const originalRenderPage = ctx.renderPage;
// You can consider sharing the same Emotion cache between all the SSR requests to speed up performance.
// However, be aware that it can have global side effects.
const cache = createEmotionCache();
const { extractCriticalToChunks } = createEmotionServer(cache);
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: (App) =>
function EnhanceApp(props) {
return <App emotionCache={cache} {...props} />;
},
});
const initialProps = await Document.getInitialProps(ctx);
// This is important. It prevents Emotion to render invalid HTML.
// See https://github.com/mui/material-ui/issues/26561#issuecomment-855286153
const emotionStyles = extractCriticalToChunks(initialProps.html);
const emotionStyleTags = emotionStyles.styles.map((style) => (
<style
data-emotion={`${style.key} ${style.ids.join(" ")}`}
key={style.key}
// eslint-disable-next-line react/no-danger
dangerouslySetInnerHTML={{ __html: style.css }}
/>
));
return {
...initialProps,
emotionStyleTags,
};
};
MyDocument.propTypes = {
emotionStyleTags: PropTypes.array.isRequired,
};
_app.js
import { Footer, Navbar } from "@/components";
import ScrollToTop from "@/components/ScrollToTop";
import GlobalStyles from "@/globalStyles";
import "@/styles/globals.css";
import { CircularProgress } from "@mui/material";
import { useRouter } from "next/router";
import React from "react";
import { CacheProvider } from "@emotion/react";
import createEmotionCache from "../createEmotionCache";
import PropTypes from "prop-types";
const clientSideEmotionCache = createEmotionCache();
export default function MyApp(props) {
const router = useRouter();
const [isLoading, setIsLoading] = React.useState(false);
const { Component, emotionCache = clientSideEmotionCache, pageProps } = props;
React.useEffect(() => {
const handleRouteChangeStart = (url, { shallow }) => {
setIsLoading(true);
};
const handleRouteChangeComplete = (url, { shallow }) => {
setIsLoading(false);
};
router.events.on("routeChangeStart", handleRouteChangeStart);
router.events.on("routeChangeComplete", handleRouteChangeComplete);
return () => {
router.events.on("routeChangeStart", handleRouteChangeStart);
router.events.on("routeChangeComplete", handleRouteChangeComplete);
};
});
return (
<CacheProvider value={emotionCache}>
{isLoading ? (
<div
style={{
width: "100vw",
height: "100vh",
textAlign: "center",
marginTop: "15%",
}}
>
<CircularProgress size="30vh" />
</div>
) : (
<>
<GlobalStyles />
<ScrollToTop />
<Navbar />
<Component {...pageProps} />
<Footer />
</>
)}
</CacheProvider>
);
}
MyApp.propTypes = {
Component: PropTypes.elementType.isRequired,
emotionCache: PropTypes.object,
pageProps: PropTypes.object.isRequired,
};
createEmotionCache.js
import createCache from "@emotion/cache";
const isBrowser = typeof document !== "undefined";
// On the client side, Create a meta tag at the top of the <head> and set it as insertionPoint.
// This assures that MUI styles are loaded first.
// It allows developers to easily override MUI styles with other styling solutions, like CSS modules.
export default function createEmotionCache() {
let insertionPoint;
if (isBrowser) {
const emotionInsertionPoint = document.querySelector(
'meta[name="emotion-insertion-point"]'
);
insertionPoint = emotionInsertionPoint ?? undefined;
}
return createCache({ key: "mui-style", insertionPoint });
}
next.config.js
/** @type {import('next').NextConfig} */
const nextConfig = {
// swcMinify: true,
// compiler: {
// // Enables the styled-components SWC transform
// styledComponents: true,
// },
reactStrictMode: true,
images: {
remotePatterns: [
{
protocol: "https",
hostname: "**",
},
],
},
};
module.exports = nextConfig;
How can I always show the frontend with styles always?
I am unable to find a solution to this problem