4

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

0 Answers0