import React from 'react' import Document, { Html, Head, Main, NextScript } from 'next/document' import { ServerStyleSheets } from '@material-ui/core/styles' import theme from '../components/theme' class MyDocument extends Document { render() { return ( <Html lang="en"> <Head> <meta charSet="utf-8" /> {/* PWA primary color */} <meta name="theme-color" content={theme.palette.primary.main} /> <link rel="preconnect" href="https://fonts.googleapis.com" crossOrigin="anonymous" /> <link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" /> </Head> <body> <Main /> <NextScript /> </body> </Html> ) } } MyDocument.getInitialProps = async ctx => { // 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 // Render app and page and get the context of the page with collected side effects. const sheets = new ServerStyleSheets() const originalRenderPage = ctx.renderPage ctx.res.setHeader('service-worker-allowed', '/') ctx.renderPage = async () => { const document = originalRenderPage({ enhanceApp: App => props => sheets.collect(<App {...props} />), }) return document } const initialProps = await Document.getInitialProps(ctx) return { ...initialProps, // Styles fragment is rendered after the app and page rendering finish. styles: ( <> {initialProps.styles} {sheets.getStyleElement()} </> ), } } export default MyDocument