Why are my Material UI styles missing when using Prerender with a React app?
Emotion (used by Material UI) may not render styles correctly during prerendering unless configured to detect Prerender’s user agent.
Issue Overview
When using Emotion-based styling (e.g., Material UI) in a React app, it's possible to encounter issues where some or all CSS styles do not appear in your prerendered pages. This results in visual regressions such as:
- Pages missing layout and visual styling when viewed from the Prerender cache
- Browser console warnings indicating that unstyled or partially styled content is being shown
This issue can impact SEO appearance and customer experience, as bots and first-time users may see broken or unthemed content. The root cause is usually related to how Emotion optimizes CSS rendering based on whether or not it detects server-side rendering.
Possible Causes / Scenarios
Material UI (Emotion) disables full styles for non-browser agents
- Emotion’s “speedy” mode — which boosts performance — skips injecting full styles during prerendering unless the configuration specifically disables it for bots like Prerender.
Server rendering does not properly detect and respond to Emotion’s requirements
- If your Express server setup doesn’t route correctly or isn't tuned to handle SSR edge cases, Emotion won’t be able to hydrate or include the appropriate styles on the initial load — particularly when serving static output via routes intended for crawling.
Solution Steps / Troubleshooting Guide
Step 1: Check the User Agent for Prerender
Ensure that your application detects if the page is being rendered for Prerender by inspecting the userAgent
. This tells Emotion whether to operate in full server-rendering mode or client-style-only mode.
You can inspect the user agent with the following:
const speedy = navigator.userAgent.toLowerCase().indexOf("prerender") === -1;
In this case, we set speedy
to false
when Prerender is detected.
Step 2: Create a Cache Configuration for Emotion
Emotion needs explicit instructions to cache styles differently for Prerender’s static rendering.
Update your App.js
file:
import { CacheProvider } from '@emotion/react';
import createCache from "@emotion/cache";
const speedy = navigator.userAgent.toLowerCase().indexOf("prerender") === -1;
const emotionCache = createCache({
key: "emotion-cache",
speedy: speedy,
});
function App() {
return (
<CacheProvider value={emotionCache}>
{/* App content here */}
</CacheProvider>
);
}
export default App;
Code Explanation:
CacheProvider
: Wraps your entire app and allows Emotion styles to inject correctly.createCache
: Thespeedy
property is crucial—setting it tofalse
ensures that Emotion renders full styles during SSR when Prerender is crawling your app.
Step 3: Adjust Your Server-side Rendering Logic
Ensure your Express.js middleware is set up correctly to route SSR pages through index.html
, particularly for client-rendered paths that don’t include file extensions (e.g., /about
, not /about.html
).
Here’s a minimal example:
app.use(
"/",
(req, res, next) => {
// URLs that don't include extensions are assumed to be routes handled by React Router
const extRegex = /\/[^.]+$/; // Matches URLs that do not contain a period (i.e., no file extension)
if (extRegex.test(req.url)) {
// Rewrite the URL to serve index.html (for client-side routing like React Router)
req.url += "/index.html";
}
next();
},
express.static(BUILD) // serve static files from the build directory
);
Additional Tips / Best Practices
- Always test your app’s output in a saved version or by visiting your Prerendered page directly to verify styling is correct.
- Add user-agent checks throughout SSR logic, especially when using CSS-in-JS libraries.
- Run manual cache clear and recache operations in the Prerender dashboard if your styles seem to get "stuck" after deployment.
When to Contact Support
If you've implemented Emotion configuration and adjusted your Express rendering logic, but CSS is still not rendering correctly:
- Provide a URL where the issue is visible
- Include a screenshot showing the broken or unstyled content
- Share your current Emotion and Material UI setup, including how you detect the Prerender user agent
You can reach us at support@prerender.io and we'll help investigate further.