You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Added all the code as per the official examples of mui with next js
UI is breaking
Current behavior 😯
UI is breaking
Expected behavior 🤔
No UI break when working with SSR, SSG
Context 🔦
pages/_app.tsx
import React, { useEffect } from 'react';
import type { AppContext, AppInitialProps, AppLayoutProps } from 'next/app';
import type { NextComponentType } from 'next';
import PropTypes from 'prop-types';
import counterpart from 'counterpart';
import hi from 'translations/hi.json';
import en from 'translations/en.json';
import HeadTag from 'components/Root/HeadTag';
import usePageProgressBar from 'hooks/usePageProgressBar';
import { languagesKey } from 'Constants/lang';
import { toast } from 'react-toastify';
import wrapper from 'reduxSM/store';
import { injectStyle } from 'react-toastify/dist/inject-style';
import { CacheProvider, EmotionCache } from '@emotion/react';
import createEmotionCache from 'utils/createEmotionCache';
import { useRouter } from 'next/router';
import {
Hydrate,
QueryClient,
QueryClientProvider,
} from '@tanstack/react-query';
import APP_ENVIRONMENTS from 'Constants/appEnvironments';
import { ReactQueryDevtools } from '@tanstack/react-query-devtools';
import 'styles/globals.scss';
import 'styles/globals.css';
import useInitUserPreferences from 'appHooks/useInitUserPreferences';
import lightTheme from 'theme/light';
import CssBaseline from '@mui/material/CssBaseline';
import { ThemeProvider } from '@mui/material/styles';
counterpart.registerTranslations(languagesKey.ENGLISH, en);
counterpart.registerTranslations(languagesKey.HINDI, hi);
toast.configure({
closeOnClick: true,
autoClose: 3000,
theme: 'colored',
limit: 2,
hideProgressBar: true,
});
// Client-side cache, shared for the whole session of the user in the browser.
const clientSideEmotionCache = createEmotionCache();
interface IAppProps extends AppLayoutProps<React.ReactPortal> {
emotionCache?: EmotionCache;
}
const MyApp: NextComponentType<AppContext, AppInitialProps, AppLayoutProps> = ({
Component,
pageProps,
emotionCache = clientSideEmotionCache,
}: IAppProps) => {
const [queryClient] = React.useState(
() =>
new QueryClient({
defaultOptions: {
queries: {
staleTime: 300000, // 5 mins
refetchOnWindowFocus: false,
retry: 1,
},
mutations: {
retry: 1,
},
},
})
);
const router = useRouter();
useInitUserPreferences();
useEffect(() => {
if (typeof window !== 'undefined') {
if (router.pathname !== '/') {
injectStyle();
}
}
}, [router.pathname]);
usePageProgressBar();
const getLayout = Component.getLayout || ((page: React.ReactNode) => page);
return (
<CacheProvider value={emotionCache}>
<HeadTag />
<ThemeProvider theme={lightTheme}>
<CssBaseline />
<QueryClientProvider client={queryClient}>
{/* @ts-ignore */}
<Hydrate state={pageProps.dehydratedState}>
{/* @ts-ignore */}
{getLayout(<Component {...pageProps} />)}
{process.env.NEXT_PUBLIC_APP_ENV !==
APP_ENVIRONMENTS.PRODUCTION && (
<ReactQueryDevtools
initialIsOpen={false}
position="bottom-right"
/>
)}
</Hydrate>
</QueryClientProvider>
</ThemeProvider>
</CacheProvider>
);
};
MyApp.propTypes = {
Component: PropTypes.func.isRequired,
pageProps: PropTypes.shape({}).isRequired,
};
// * Wrapper created using next-redux-wrapper
export default wrapper.withRedux(MyApp);
createEmotionCache util
import createCache from '@emotion/cache';
const isBrowser = typeof document !== 'undefined';
// On the client side, Create a meta tag at the top of the <head> and set it as insertionPoint.
// This assures that MUI styles are loaded first.
// It allows developers to easily override MUI styles with other styling solutions, like CSS modules.
export default function createEmotionCache() {
let insertionPoint;
if (isBrowser) {
const emotionInsertionPoint = document.querySelector(
'meta[name="emotion-insertion-point"]'
);
insertionPoint = emotionInsertionPoint ?? undefined;
}
return createCache({ key: 'mui-style', insertionPoint, prepend: false });
}
_document.tsx
import * as React from 'react';
import Document, { Html, Head, Main, NextScript } from 'next/document';
import createEmotionServer from '@emotion/server/create-instance';
import createEmotionCache from '../utils/createEmotionCache';
import lightTheme from 'theme/light';
export default class MyDocument extends Document {
render() {
return (
<Html lang="en">
<Head>
<meta charSet="utf-8" />
<meta name="theme-color" content={lightTheme.palette.primary.main} />
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link
rel="preconnect"
href="https://fonts.gstatic.com"
crossOrigin="anonymous"
/>
<link
rel="stylesheet"
href="https://cdnjs.cloudflare.com/ajax/libs/animate.css/3.5.2/animate.min.css"
/>
<link
href="https://fonts.googleapis.com/css2?family=Montserrat:wght@100;200;300;500;600;700&display=swap"
rel="stylesheet"
/>
<link rel="preconnect" href="https://neuro-node.herokuapp.com" />
{/* Inject MUI styles first to match with the prepend: true configuration. */}
{(this.props as any).emotionStyleTags}
</Head>
<body>
<Main />
<div id="huvile-portal" />
<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);
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: (App: any) =>
function EnhanceApp(props) {
return <App emotionCache={cache} {...props} />;
},
});
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,
emotionStyleTags,
};
};
Since the issue is missing key information and has been inactive for 7 days, it has been automatically closed. If you wish to see the issue reopened, please provide the missing information.
Duplicates
Latest version
Steps to reproduce 🕹
Steps:
Current behavior 😯
UI is breaking
Expected behavior 🤔
No UI break when working with SSR, SSG
Context 🔦
pages/_app.tsx
createEmotionCache util
_document.tsx
package.json dependencies
"@emotion/cache": "^11.9.3",
"@emotion/react": "^11.9.3",
"@emotion/server": "^11.4.0",
"@emotion/styled": "^11.9.3",
"@material-ui/core": "^4.12.3",
"@material-ui/icons": "^4.11.2",
"@mui/icons-material": "^5.8.4",
"@mui/lab": "^5.0.0-alpha.86",
"@mui/material": "^5.8.4",
"@mui/styles": "^5.8.4",
"@mui/system": "^5.8.4",
"next": "^12.3.0",
"react": "^18.1.0",
"react-dom": "^18.1.0"
Your environment 🌎
npx @mui/envinfo
The text was updated successfully, but these errors were encountered: