Spaces:
Runtime error
Runtime error
import * as React from "react"; | |
import Document, { | |
DocumentContext, | |
DocumentProps, | |
Head, | |
Html, | |
Main, | |
NextScript, | |
} from "next/document"; | |
import createEmotionServer from "@emotion/server/create-instance"; | |
import { AppType } from "next/app"; | |
import { roboto } from "@/lib/theme"; | |
import createEmotionCache from "@/lib/createEmotionCache"; | |
import { MyAppProps } from "./_app"; | |
import { getInitColorSchemeScript } from "@mui/material/styles"; | |
interface MyDocumentProps extends DocumentProps { | |
emotionStyleTags: JSX.Element[]; | |
} | |
export default function MyDocument({ emotionStyleTags }: MyDocumentProps) { | |
return ( | |
<Html lang="en" className={roboto.className}> | |
<Head> | |
<link rel="shortcut icon" href="/favicon.ico" /> | |
<meta name="emotion-insertion-point" content="" /> | |
{emotionStyleTags} | |
</Head> | |
<body> | |
{getInitColorSchemeScript()} | |
<Main /> | |
<NextScript /> | |
</body> | |
</Html> | |
); | |
} | |
// `getInitialProps` belongs to `_document` (instead of `_app`), | |
// it's compatible with static-site generation (SSG). | |
MyDocument.getInitialProps = async (ctx: DocumentContext) => { | |
// 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 | |
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: React.ComponentType<React.ComponentProps<AppType> & MyAppProps>) => | |
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, | |
}; | |
}; | |