Created
February 23, 2022 18:36
-
-
Save isomorpheric/207244e40298cc8d4d6c425bdc361e78 to your computer and use it in GitHub Desktop.
Example MUI v5 Document Ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import * as React from 'react'; | |
import Document, { Html, Head, Main, NextScript } from 'next/document'; | |
import createEmotionServer from '@emotion/server/create-instance'; | |
import createEmotionCache from '../utility/createEmotionCache'; | |
export default class MyDocument extends Document { | |
render() { | |
return ( | |
<Html lang="en"> | |
<Head> | |
<link | |
rel="stylesheet" | |
href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap" | |
/> | |
</Head> | |
<body> | |
<Main /> | |
<NextScript /> | |
</body> | |
</Html> | |
); | |
} | |
} | |
// `getInitialProps` belongs to `_document` (instead of `_app`), | |
// it's compatible with static-site generation (SSG). | |
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 | |
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); | |
/* eslint-disable */ | |
ctx.renderPage = () => | |
originalRenderPage({ | |
enhanceApp: (App: any) => (props) => | |
<App emotionCache={cache} {...props} />, | |
}); | |
/* eslint-enable */ | |
const initialProps = await Document.getInitialProps(ctx); | |
// This is important. It prevents emotion to render invalid HTML. | |
// See https://github.com/mui-org/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, | |
// Styles fragment is rendered after the app and page rendering finish. | |
styles: [ | |
...React.Children.toArray(initialProps.styles), | |
...emotionStyleTags, | |
], | |
}; | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment