Created
July 3, 2023 10:37
-
-
Save yhunko/8151608564ae809b21cd72c47d350861 to your computer and use it in GitHub Desktop.
Next.js + MUI + Emotion server cache
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
// imports ... | |
const clientSideEmotionCache = createEmotionCache(); | |
export type CustomAppProps = AppProps & { | |
Component: NextPageWithLayout<any>; | |
emotionCache?: EmotionCache; | |
}; | |
function MyApp({ Component, pageProps, emotionCache = clientSideEmotionCache }: CustomAppProps) { | |
// ... | |
return ( | |
// ... | |
<CacheProvider value={emotionCache}> | |
<ThemeProvider theme={themeOptions}> | |
// ... | |
</ThemeProvider> | |
</CacheProvider> | |
) | |
} |
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 React from 'react'; | |
import createEmotionServer from '@emotion/server/create-instance'; | |
import { AppType } from 'next/app'; | |
import Document, { | |
DocumentContext, | |
DocumentProps, | |
Head, | |
Html, | |
Main, | |
NextScript, | |
} from 'next/document'; | |
import { createEmotionCache } from 'styles/createEmotionCache'; | |
import { CustomAppProps } from './_app'; | |
type CustomDocumentProps = DocumentProps & { | |
emotionStyleTags: JSX.Element[]; | |
}; | |
function CustomDocument({ emotionStyleTags }: CustomDocumentProps) { | |
return ( | |
<Html lang="en"> | |
<Head>{emotionStyleTags}</Head> | |
<body id={'twRoot'}> | |
<Main /> | |
<NextScript /> | |
</body> | |
</Html> | |
); | |
} | |
CustomDocument.getInitialProps = async (ctx: DocumentContext) => { | |
const originalRenderPage = ctx.renderPage; | |
const cache = createEmotionCache(); | |
const { extractCriticalToChunks } = createEmotionServer(cache); | |
ctx.renderPage = () => | |
originalRenderPage({ | |
enhanceApp: (App: React.ComponentType<React.ComponentProps<AppType> & CustomAppProps>) => | |
function EnhanceApp(props) { | |
return <App emotionCache={cache} {...props} />; | |
}, | |
}); | |
const initialProps = await Document.getInitialProps(ctx); | |
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, | |
}; | |
}; | |
export default CustomDocument; |
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 createCache from '@emotion/cache'; | |
export const createEmotionCache = () => createCache({ key: 'css', prepend: true }); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment