Skip to content

Instantly share code, notes, and snippets.

@yhunko
Created July 3, 2023 10:37
Show Gist options
  • Save yhunko/8151608564ae809b21cd72c47d350861 to your computer and use it in GitHub Desktop.
Save yhunko/8151608564ae809b21cd72c47d350861 to your computer and use it in GitHub Desktop.
Next.js + MUI + Emotion server cache
// 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>
)
}
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;
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