when i start the development server all the styles are properly loaded but gone after reload. I'm using nextJs and this problem is due to SSR of nextJs. I know but can't configure properly and need help. I added _document.js, created emotioncache file and updated _app.js. But after all this may be something is missing.
my _app.js file
import { CacheProvider } from '@emotion/react';
import { ThemeProvider, CssBaseline } from '@mui/material';
import createEmotionCache from '../utility/createEmotionCache';
import lightTheme from '../styles/theme/lightTheme';
import Navbar from '@/components/Navbar';
import Drawer from '@/components/Drawer';
import { Stack, Box } from '@mui/material';
import '@/styles/globals.css';
const clientSideEmotionCache = createEmotionCache();
export default function App(props) {
const { Component, emotionCache = clientSideEmotionCache, pageProps } = props;
return (
<CacheProvider value={emotionCache}>
<ThemeProvider theme={lightTheme}>
<CssBaseline />
<Box sx={{ height: '100vh', overflow: 'hidden' }}>
<Navbar />
<Stack direction="row" spacing={3} sx={{ marginTop: '8px' }}>
<Drawer />
<Component {...pageProps} />
</Stack>
</Box>
</ThemeProvider>
</CacheProvider>
)
}
my document.js file
import * as React from 'react';
import Document, { Html, Head, Main, NextScript } from 'next/document';
import createEmotionServer from '@emotion/server/create-instance';
import createEmotionCache from '../utility/createEmotionCache';
export default class MyDocument extends Document {
render() {
return (
<Html lang="en">
<Head>
<link
rel="stylesheet"
href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"
/>
</Head>
<body>
<Main />
<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);
/* eslint-disable */
ctx.renderPage = () =>
originalRenderPage({
enhanceApp: (App) =>
function EnhanceApp(props) {
return <App emotionCache={cache} {...props} />;
},
});
/* eslint-enable */
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,
// Styles fragment is rendered after the app and page rendering finish.
styles: [
...React.Children.toArray(initialProps.styles),
...emotionStyleTags,
],
};
};
createEmotionCache file
import createCache from '@emotion/cache';
const createEmotionCache = () => {
return createCache({ key: 'css', prepend: true });
};
export default createEmotionCache;
also added a theme.js
import { createTheme } from '@mui/material/styles';
const lightTheme = createTheme({
palette: {
mode: 'light',
},
});
export default lightTheme;
my package.json file
{
"name": "new",
"version": "0.1.0",
"private": true,
"scripts": {
"dev": "next dev",
"build": "next build",
"start": "next start",
"lint": "next lint"
},
"dependencies": {
"@emotion/cache": "^11.10.7",
"@emotion/react": "^11.10.6",
"@emotion/server": "^11.10.0",
"@emotion/styled": "^11.10.6",
"@mui/icons-material": "^5.11.16",
"@mui/material": "^5.12.0",
"@mui/styles": "^5.12.0",
"axios": "^1.3.6",
"eslint": "8.38.0",
"eslint-config-next": "13.3.0",
"next": "13.3.0",
"react": "18.2.0",
"react-dom": "18.2.0"
}
}
this is navigation bar component using makestyles.
import React from 'react'
import { AppBar, Box, Stack, Toolbar, IconButton, Typography, Icon } from '@mui/material'
import { makeStyles } from '@mui/styles';
//Icons
import MenuIcon from '@mui/icons-material/Menu';
import YouTubeIcon from '@mui/icons-material/YouTube';
import ClearIcon from '@mui/icons-material/Clear';
import SearchIcon from '@mui/icons-material/Search';
import MicIcon from '@mui/icons-material/Mic';
import VideoCallIcon from '@mui/icons-material/VideoCall';
import NotificationsNoneIcon from '@mui/icons-material/NotificationsNone';
//CSS Styles
const useStyles = makeStyles((theme) => ({
appbar: {
backgroundColor: 'white',
color: 'black',
boxShadow: 'none',
height: '50px',
display: 'flex',
position: 'relative',
flexDirection: 'column',
justifyContent: 'center'
},
toolbar: {
height: '50px',
padding: '0px 8px',
display: 'flex',
justifyContent: 'space-between',
},
searchbar: {
height: '30px',
padding: '0px 0px 0px 12px',
border: '1px solid rgba(184, 179, 179, 0.295)',
borderRight: 'none',
borderRadius: '30px 0px 0px 30px',
width: '500px',
'&:focus': {
outline: 'none',
},
'&::placeholder': {
color: 'rgba(48, 46, 46, 0.295)',
fontSize: '14px',
}
},
searchwrapper: {
display: 'flex',
justifyContent: 'center'
},
searchbutton: {
height: '30px',
padding: '0px 12px 0px 8px',
display: 'flex',
flexDirection: 'column',
justifyContent: 'center',
border: '1px solid rgba(184, 179, 179, 0.295)',
borderRadius: '0px 30px 30px 0px',
background: 'rgba(184, 179, 179, 0.295)'
}
}));
const NavMain = () => {
return (
<Stack direction="row" spacing={0.8} alignItems="center">
<IconButton >
<MenuIcon sx={{ fontSize: '28px', color: 'black' }} />
</IconButton>
<IconButton>
<YouTubeIcon sx={{ fontSize: '28px', color: 'red' }} />
<Typography variant="h6">Youtube</Typography>
</IconButton>
</Stack>
);
}
const NavSearch = () => {
const classes = useStyles();
return (
<Stack direction="row" spacing={0.8} alignItems="center" sx={{ marginLeft: '120px' }}>
<div className={classes.searchwrapper}>
<input
placeholder='Search'
className={classes.searchbar}
/>
<Icon className={classes.searchbutton} >
<SearchIcon />
</Icon>
</div>
<IconButton>
<MicIcon sx={{ color: 'black' }} />
</IconButton>
</Stack>
);
}
const NavEnd = () => {
const classes = useStyles();
return (
<Stack direction="row" spacing={1} alignItems="center">
<IconButton>
<VideoCallIcon sx={{ color: 'black' }} />
</IconButton>
<IconButton>
<NotificationsNoneIcon sx={{ color: 'black' }} />
</IconButton>
{/* <Icon>
</Icon> */}
</Stack>
)
}
const Navbar = () => {
const classes = useStyles();
return (
<AppBar className={classes.appbar}>
<Toolbar className={classes.toolbar}>
<NavMain />
<NavSearch />
<NavEnd />
</Toolbar>
</AppBar>
)
}
export default Navbar;
notice that after reload only styles are gone rest html and js are there.