diff --git a/.eslintrc.js b/.eslintrc.js index df426d33c7..bbae2e5de0 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -26,6 +26,9 @@ module.exports = { { files: ['src/frontend/next/**/*.ts', 'src/frontend/next/**/*.tsx'], plugins: ['@typescript-eslint'], + env: { + browser: true, + }, rules: { 'react/prop-types': 'off', 'react/react-in-jsx-scope': 'off', diff --git a/src/frontend/next/src/pages/_app.tsx b/src/frontend/next/src/pages/_app.tsx index 3f6dbc4c92..ba1dd792c5 100644 --- a/src/frontend/next/src/pages/_app.tsx +++ b/src/frontend/next/src/pages/_app.tsx @@ -1,7 +1,17 @@ +import { useEffect } from 'react'; import { AppProps } from 'next/app'; import '../styles/globals.css'; +// Reference: https://github.com/mui-org/material-ui/blob/master/examples/nextjs/pages/_app.js const App = ({ Component, pageProps }: AppProps) => { + // This hook is for ensuring the styling is 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); + } + }, []); return ; }; diff --git a/src/frontend/next/src/pages/_document.tsx b/src/frontend/next/src/pages/_document.tsx new file mode 100644 index 0000000000..91375b8f98 --- /dev/null +++ b/src/frontend/next/src/pages/_document.tsx @@ -0,0 +1,44 @@ +import { Children } from 'react'; +import Document, { Html, Head, Main, NextScript, DocumentContext } from 'next/document'; +import { ServerStyleSheets } from '@material-ui/core/styles'; + +// Reference: https://github.com/mui-org/material-ui/blob/master/examples/nextjs/pages/_document.js +class MyDocument extends Document { + static async getInitialProps(ctx: DocumentContext) { + const initialProps = await Document.getInitialProps(ctx); + return { ...initialProps }; + } + + render() { + return ( + + + +
+ + + + ); + } +} + +MyDocument.getInitialProps = async (ctx) => { + // Render app and page and get the context of the page with collected side effects. + const sheets = new ServerStyleSheets(); + const originalRenderPage = ctx.renderPage; + + ctx.renderPage = () => + originalRenderPage({ + enhanceApp: (App) => (props) => sheets.collect(), + }); + + const initialProps = await Document.getInitialProps(ctx); + + return { + ...initialProps, + // Styles fragment is rendered after the app and page rendering finish. + styles: [...Children.toArray(initialProps.styles), sheets.getStyleElement()], + }; +}; + +export default MyDocument;