Emotion Theme with Remix doesn't work properly
Nobody has claimed this yet.
Assessment
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Newbie friendliness
- 35/100
- Issue type
- Bug
- Clarity
- Needs clarification
- Activity status
- Stale
- Tech stack
- react, typescript
Research direction
Start with the Remix + MUI example linked in the issue, especially app/entry.server.tsx, and compare it with the shown SSR provider setup. Reproduce the behavior using the provided StyledDiv and server render path. Done means the configured theme is available to styled components and useTheme() during SSR, with the client behavior still working.
Written by the indexing model from the issue text.
Description
Hello,
I'm using Remix with Emotion and have encountered a server-side rendering issue: when I wrap the app in <ThemeProvider> from @emotion/react and try to access the theme inside a styled component (or using useTheme()), the theme object is {} during SSR. On the client side, everything works fine.
I'm basing my setup on this Remix + MUI example, with slight modifications:
https://github.com/mui/material-ui/blob/master/examples/material-ui-remix-ts/app/entry.server.tsx
Do you have a relevant example with a theme, or maybe you know where I made a mistake in the configuration?
Here is the relevant SSR configuration:
const handleBrowserRequest = (
request: Request,
responseStatusCode: number,
responseHeaders: Headers,
remixContext: EntryContext,
) => {
const cache = createEmotionCache();
const { extractCriticalToChunks } = createEmotionServer(cache);
function MuiRemixServer() {
return (
<ServerStyleContext.Provider value={null}>
<CacheProvider value={cache}>
<ThemeProvider theme={theme}>
<RemixServer context={remixContext} url={request.url} />
</ThemeProvider>
</CacheProvider>
</ServerStyleContext.Provider>
);
}
// Render the component to a string.
const html = ReactDOMServer.renderToString(<MuiRemixServer />);
// Grab the CSS from emotion
const chunks = extractCriticalToChunks(html);
const markup = ReactDOMServer.renderToString(
<ServerStyleContext.Provider value={chunks.styles}>
<CacheProvider value={cache}>
<ThemeProvider theme={theme}>
<CssBaseline />
<RemixServer context={remixContext} url={request.url} />
</ThemeProvider>
</CacheProvider>
</ServerStyleContext.Provider>,
);
responseHeaders.set("Content-Type", "text/html");
// Enhanced cache control headers to prevent aggressive browser caching
responseHeaders.set("Cache-Control", "no-store, no-cache, must-revalidate, proxy-revalidate");
responseHeaders.set("Surrogate-Control", "no-store");
responseHeaders.set("Pragma", "no-cache");
responseHeaders.set("Expires", "0");
// Add a unique timestamp to force browsers to refetch resources
responseHeaders.set("X-Content-Timestamp", new Date().getTime().toString());
return new Response(`<!DOCTYPE html>${markup}`, {
status: responseStatusCode,
headers: responseHeaders,
});
};
A simplified styled component that reproduces the issue:
import styled from "@emotion/styled";
export const StyledDiv = styled.div`
${({ theme }) => {
console.log("Theme on server:", theme); // Outputs {}
return "";
}}
`;
Environment information:
reactversion: 18.2.0@emotion/reactversion: 11.13.3@emotion/serverversion: 11.11.0@mui/materialversion: 6.1.6@remix-run/devversion: 2.16.4
- Dominant language
- TypeScript
- Stars
- 1.2k
- Forks
- 235
- Avg merge
- 2h 5m
- Merged PRs (30d)
- 2
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
More from remix-run/examples
-
Difficulty 4/5 3-5 days Newbie friendliness 15/100
-
Difficulty 3/5 1-2 days Newbie friendliness 25/100
-
Difficulty 4/5 3-5 days Newbie friendliness 25/100
-
Difficulty 5/5 Over a week Newbie friendliness 30/100
-
example request
Difficulty 5/5 Over a week Newbie friendliness 20/100
All issues in remix-run/examples
Similar issues
-
clawsweeper:fix-shape-clear clawsweeper:queueable-fix clawsweeper:source-repro impact:ux-friction issue-rating: 🦞 diamond lobster no-stale P3
Difficulty 2/5 1-3 hours Newbie friendliness 78/100
-
community first-timers-only good first issue hacktoberfest help wanted low hanging fruit up-for-grabs
Difficulty 1/5 Under an hour Newbie friendliness 76/100
-
code-quality refactoring
Difficulty 2/5 1-3 hours Newbie friendliness 84/100
github/gh-aw-firewall#8816 ·
-
integration:quickjs org:external priority:backlog topic:code-interpreter topic:middleware type:feature
Difficulty 2/5 1-3 hours Newbie friendliness 74/100
langchain-ai/deepagents#6450 ·
-
Difficulty 1/5 Under an hour Newbie friendliness 88/100
vercel/react-tweet#225 ·