diff --git a/striker-ui/lib/create_emotion_cache/createEmotionCache.ts b/striker-ui/lib/create_emotion_cache/createEmotionCache.ts new file mode 100644 index 00000000..e221910d --- /dev/null +++ b/striker-ui/lib/create_emotion_cache/createEmotionCache.ts @@ -0,0 +1,8 @@ +import { EmotionCache } from '@emotion/react'; +import createCache from '@emotion/cache'; + +const createEmotionCache = (): EmotionCache => { + return createCache({ key: 'css' }); +}; + +export default createEmotionCache; diff --git a/striker-ui/pages/_app.tsx b/striker-ui/pages/_app.tsx index 9d2dff4c..75a5d7bb 100644 --- a/striker-ui/pages/_app.tsx +++ b/striker-ui/pages/_app.tsx @@ -1,26 +1,32 @@ -import { useEffect } from 'react'; import { AppProps } from 'next/app'; -import { ThemeProvider } from '@material-ui/core/styles'; +import { ThemeProvider } from '@mui/material'; +import { CacheProvider, EmotionCache } from '@emotion/react'; + +import createEmotionCache from '../lib/create_emotion_cache/createEmotionCache'; import theme from '../theme'; import '../styles/globals.css'; -const App = ({ Component, pageProps }: AppProps): JSX.Element => { - // This hook is for ensuring the styling is in sync between client and server - useEffect(() => { - // Remove the server-side injected CSS. - const jssStyles = document.querySelector('#jss-server-side'); - if (jssStyles) { - jssStyles.parentElement?.removeChild(jssStyles); - } - }, []); +const clientSideEmotionCache = createEmotionCache(); + +interface MyAppProps extends AppProps { + // eslint-disable-next-line react/require-default-props + emotionCache?: EmotionCache; +} +const App = ({ + Component, + emotionCache = clientSideEmotionCache, + pageProps, +}: MyAppProps): JSX.Element => { return ( - - - + + + + + ); }; diff --git a/striker-ui/pages/_document.tsx b/striker-ui/pages/_document.tsx index 14b48a82..3b0d58c5 100644 --- a/striker-ui/pages/_document.tsx +++ b/striker-ui/pages/_document.tsx @@ -1,34 +1,52 @@ import Document, { DocumentInitialProps, DocumentContext } from 'next/document'; -import { ServerStyleSheets as MaterialUiServerStyleSheets } from '@material-ui/styles'; -// import { ServerStyleSheet as StyledComponentSheets } from 'styled-components'; +import createEmotionServer from '@emotion/server/create-instance'; + +import createEmotionCache from '../lib/create_emotion_cache/createEmotionCache'; class MyDocument extends Document { static async getInitialProps( ctx: DocumentContext, ): Promise { - const materialUiSheets = new MaterialUiServerStyleSheets(); const originalRenderPage = ctx.renderPage; + const emotionCache = createEmotionCache(); + const { extractCriticalToChunks } = createEmotionServer(emotionCache); + ctx.renderPage = () => originalRenderPage({ - /* eslint-disable react/display-name */ - enhanceApp: (App) => (props) => - materialUiSheets.collect( - , - ), + // Temporary; the implicit type of App doesn't include the prop "emotionCache" thus typescript will complain. + // Find a way to extend the implicit type to add the cache property. + // eslint-disable-next-line @typescript-eslint/no-explicit-any + enhanceApp: (App: any) => + function EnhanceApp(props) { + return ( + + ); + }, }); const initialProps = await Document.getInitialProps(ctx); + const emotionStyles = extractCriticalToChunks(initialProps.html); + const emotionStyleTags = emotionStyles.styles.map((style) => ( +