import * as React from 'react';
import { AppType, MyAppProps } from 'next/app';
import { default as Document, DocumentContext, DocumentProps, Head, Html, Main, NextScript } from 'next/document';
import createEmotionServer from '@emotion/server/create-instance';
import InitColorSchemeScript from '@mui/joy/InitColorSchemeScript';
import { Brand } from '~/common/app.config';
import { createEmotionCache } from '~/common/app.theme';
interface MyDocumentProps extends DocumentProps {
emotionStyleTags: React.JSX.Element[];
}
export default function MyDocument({ emotionStyleTags }: MyDocumentProps) {
return (
{/* Meta (missing Title, set by the App or Page) */}
{/* Favicons & PWA */}
{/* Opengraph */}
{Brand.URIs.CardImage && }
{/* Twitter */}
{Brand.URIs.CardImage && }
{/* Style Sheets (injected and server-side) */}
{emotionStyleTags}
);
}
// `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 & MyAppProps>) =>
function EnhanceApp(props) {
return ;
},
});
const initialProps = await Document.getInitialProps(ctx);
// Inject the comment before the HTML tag
initialProps.html = `\n${initialProps.html}`;
// 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) => (
));
return {
...initialProps,
emotionStyleTags,
};
};