I have integrated material UI in my Server side rendering app and have followed the code given here. Material UI css is been added to the html on the server side itself.
However, on the initial load, material ui styles are not applied which is causing it to flicker.
I tried using <cssbaseline>
along with the below code but did not see any difference.
Here is my code: server.js
import App from '../common/containers/App';
import { Provider } from 'react-redux';
import React from 'react';
import configureStore from '../common/store/configureStore';
import express from 'express';
import qs from 'qs';
import { renderToString } from 'react-dom/server';
import serialize from 'serialize-javascript';
import { StaticRouter, matchPath } from 'react-router-dom';
import {theme} from '../theme';
import { ServerStyleSheets, ThemeProvider } from '@material-ui/styles';
import routes from './routes'
import "../common/assets/SCSS/app.scss";
const assets = require(process.env.RAZZLE_ASSETS_MANIFEST);
const server = express();
server
.disable('x-powered-by')
.use(express.static(process.env.RAZZLE_PUBLIC_DIR))
.get('/*', (req, res) => {
const activeRoute = routes.find((route) => matchPath(req.url, route)) || {}
const promise = activeRoute.fetchInitialData
? activeRoute.fetchInitialData(req.path)
: Promise.resolve()
promise.then((apiResult) => {
const sheets = new ServerStyleSheets();
const counter = apiResult || 0;
const preloadedState = { counter };
const store = configureStore(preloadedState);
const context = {};
const markup = renderToString(
sheets.collect(
<Provider store={store}>
<ThemeProvider theme={theme}>
<StaticRouter location={req.url} context={context}>
<App />
</StaticRouter>
</ThemeProvider>
</Provider>
));
const css = sheets.toString();
const finalState = store.getState();
const html = `<!doctype html>
<html lang="">
<head>
${assets.client.css
? `<link rel="stylesheet" href="${assets.client.css}">`
: ''}
${css ? `<style id='jss-ssr'>${css}</style>` : ''}
${process.env.NODE_ENV === 'production'
? `<script src="${assets.client.js}" defer></script>`
: `<script src="${assets.client.js}" defer crossorigin></script>`}
</head>
<body>
<div id="root">${markup}</div>
<script>
window.__PRELOADED_STATE__ = ${serialize(finalState)}
</script>
</body>
</html>`
res.send(html);
});
});
export default server;
Client.js
import React,{useEffect} from 'react';
import { hydrate } from 'react-dom';
import {theme} from '../theme';
import { ThemeProvider } from '@material-ui/styles';
import { Provider } from 'react-redux';
import configureStore from '../common/store/configureStore';
import App from '../common/containers/App';
import { BrowserRouter } from "react-router-dom";
import "../common/assets/SCSS/app.scss";
import * as serviceWorker from '../serviceWorker';
import CssBaseline from '@material-ui/core/CssBaseline';
const store = configureStore(window.__PRELOADED_STATE__);
const Client = () => {
useEffect(() => {
const jssStyles = document.querySelector('#jss-ssr');
if (jssStyles) {
jssStyles.parentElement.removeChild(jssStyles);
}
}, []);
return(
<Provider store={store}>
<ThemeProvider theme={theme}>
<CssBaseline />
<BrowserRouter>
<App />
</BrowserRouter>
</ThemeProvider>
</Provider>
);
}
hydrate(<Client />,document.getElementById('root'));