_document.page.tsx
1 import createEmotionServer from '@emotion/server/create-instance'; 2 import Document, { Head, Html, Main, NextScript } from 'next/document'; 3 import * as React from 'react'; 4 5 import createEmotionCache from '../src/createEmotionCache'; 6 7 export default class MyDocument extends Document { 8 render() { 9 return ( 10 <Html lang="en"> 11 <Head> 12 <meta name="theme-color" content="#1B2030" /> 13 <link rel="icon" href="/favicon.ico" sizes="any" /> 14 <link rel="shortcut icon" href="/favicon.ico" /> 15 {/* <link rel="apple-touch-icon" sizes="16x16" href="/favicon.png" /> 16 <link rel="apple-touch-icon" sizes="32x32" href="/favicon32.png" /> 17 <link rel="shortcut icon" sizes="32x32" href="/favicon32.ico" /> 18 <link rel="apple-touch-icon" sizes="64x64" href="/favicon64.png" /> 19 <link rel="apple-touch-icon" sizes="180x180" href="/aave_icon180.png" /> */} 20 21 <link rel="manifest" href="/manifest.json" /> 22 { 23 // Inject MUI styles first to match with the prepend: true configuration. 24 // eslint-disable-next-line @typescript-eslint/no-explicit-any 25 (this.props as any).emotionStyleTags 26 } 27 </Head> 28 <body> 29 <Main /> 30 <NextScript /> 31 </body> 32 </Html> 33 ); 34 } 35 } 36 37 // `getInitialProps` belongs to `_document` (instead of `_app`), 38 // it's compatible with static-site generation (SSG). 39 MyDocument.getInitialProps = async (ctx) => { 40 // Resolution order 41 // 42 // On the server: 43 // 1. app.getInitialProps 44 // 2. page.getInitialProps 45 // 3. document.getInitialProps 46 // 4. app.render 47 // 5. page.render 48 // 6. document.render 49 // 50 // On the server with error: 51 // 1. document.getInitialProps 52 // 2. app.render 53 // 3. page.render 54 // 4. document.render 55 // 56 // On the client 57 // 1. app.getInitialProps 58 // 2. page.getInitialProps 59 // 3. app.render 60 // 4. page.render 61 62 const originalRenderPage = ctx.renderPage; 63 64 // You can consider sharing the same emotion cache between all the SSR requests to speed up performance. 65 // However, be aware that it can have global side effects. 66 const cache = createEmotionCache(); 67 const { extractCriticalToChunks } = createEmotionServer(cache); 68 69 ctx.renderPage = () => 70 originalRenderPage({ 71 // eslint-disable-next-line @typescript-eslint/no-explicit-any 72 enhanceApp: (App: any) => 73 function EnhanceApp(props) { 74 return <App emotionCache={cache} {...props} />; 75 }, 76 }); 77 78 const initialProps = await Document.getInitialProps(ctx); 79 // This is important. It prevents emotion to render invalid HTML. 80 // See https://github.com/mui-org/material-ui/issues/26561#issuecomment-855286153 81 const emotionStyles = extractCriticalToChunks(initialProps.html); 82 const emotionStyleTags = emotionStyles.styles.map((style) => ( 83 <style 84 data-emotion={`${style.key} ${style.ids.join(' ')}`} 85 key={style.key} 86 // eslint-disable-next-line react/no-danger 87 dangerouslySetInnerHTML={{ __html: style.css }} 88 /> 89 )); 90 91 return { 92 ...initialProps, 93 emotionStyleTags, 94 }; 95 };