-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Emotion in React Server Components? #2978
Comments
🤔 Wonder if this new "Float" thing has anything that is useful here for enabling CSS-in-JS + React Server Components
cc @sebmarkbage |
Some other CSS-in-JS ecosystem movement trying to support React Server Components: |
Seems like Chakra UI is going to switch away from Emotion and to a zero runtime CSS-in-JS solution called Panda:
|
Too ease the blow for everybody who is struggling with this (including me), a little consideration: If you were happy with emotion before, there is no difference right now. Client components render the same way, they render with SSR and are passed to the browser and render there as well. The difference is that the leaves are bit higher up and you need to use wrapper for direct HTML elements. Lot's of elements that do not actually render HTML elements can still use RSC, this means all your components that composite other components, like pages or layouts still benefit from RSC. import { Box } from '@mui/material' // If you've patched @mui/material to have a 'use client' on top of the actual JS file.
export async function ThisIsAServerComponent() {
const bla = await fetch()
return <Box sx={{color: 'red'}}>Hello from RSC {bla}</Box>
} There of course are long therm choices to be made to move to a build-time extraction of css-in-js or another solution, but this argument was always there. |
@Andarist we are migrating to Next.js Compatibility issuesCSS-in-JSServer components are not currently compatible with CSS-in-JS, a core feature of MUI and most component libraries, due to their closely coupled dependency, emotion. Next.js Docs highlight that CSS-in-JS is not currently supported and that Next.js/React are working on supporting this, although it’s not clear if CSS-in-JS will be supported for server components by Next.js/React alone, or more likely that library authors will also need to make changes. The next.js docs also state that MUI and emotion are also working on support, but there’s no confirmation of this or definitive answers about whether server components will be supported by MUI/emotion in the future. MUI’s options
Emotions options
Dynamic componentsMUI components use interactivity including event listeners, hooks, state and lifecycle effects. Inherently making them client components and not compatible with server components. For some MUI components this interactivity is always a requirement (e.g. all inputs, MUIs options
Current server components + MUI project migration optionsFor those intending to use server components on a new project, or refactoring an existing project using MUI, the outlook/decision currently seems to be:
|
Disclaimer: I'm not an RSC expert so take this with a grain of salt.
Next.js rushed the release of their docs without consulting library authors. The mentioned Styled-Components "support" looks almost exactly the same as the Emotion support can look like (see the comment here). There is no special API in SC that integrates with RSC in any special way. I expect that both SC and Emotion might be prone to subtle hydration bugs when using this approach though (for the majority of use cases they should be totally negligible. I don't want to raise panic over this as there is definitely nothing to panic about here, just mentioning for completeness and correctness. I don't want to claim that the mentioned support is ideal). To bring better support to Emotion we are waiting for React's new APIs that should allow us to inject styles to the streamed response without having to "listen" on what's being streamed (this is essentially how
All of those are just client components - which doesn't mean that they can't be rendered on the server. Refetches might not benefit from SSR style-injection but that shouldn't be a big deal for the majority of use cases anyway. You can totally use those in RSC, as shown by @paales here
This might require some changes in MUI. I'm not part of their team so you should raise that in their issue tracker. Likely the issue is just about adding |
This whole style extraction thing sounds like a good chunk of work slowing down fast refresh and building times or am I just being overly anxious? |
That would be similar to what react /next is doing, eg. not allowing for hooks in server components. If no hooks and no state are present, dynamic styling literally renders useless anyway... Im my opinion this is the way to go, especially considering that this would solve most of the 'performance problems' css-in-js is accused of 🍿 Having to use 2 styling libs in a project does not sound inviting imho, but it's the only way possible now 😞 |
As I understand it, the lack of the React Context API is the only reason why Emotion doesn't work with RSC. What would prevent us from using the React 18 So it seems to me that we can make Emotion work with RSC, today, I wish I had time to work on this 🙃. |
@oliviertassinari just for the record I am not sure about the example in the readme of this lib, more info here : manvalls/server-only-context#4 |
I did a POC to test RSC + Client Side Component context support using /* eslint-disable react-hooks/rules-of-hooks */
import * as React from 'react';
export const useServerCache = React.cache(() => []);
let clientContext;
function getClientCache() {
if (!clientContext) {
clientContext = React.createContext([]);
}
return clientContext;
}
export function useCache() {
try {
// React Server Component
return useServerCache();
} catch (e) {
// React Client Component
const clientContext = getClientCache();
return React.useContext(clientContext);
}
} We need to duplicate the context value. cc @Andarist How I understand things working: |
Managed to make twin.macro work with emotion package Caused the following problems: - Had to switch SWC to Babel - Had to remove Next/Font - Had to add 'use client' on layout - Had to remove Metadata - Had to manually edit scripts from react-three/drei package Not worth it Maybe later when this issue is solved: emotion-js/emotion#2978
I looked a bit closer at how the React Context API missing on the server-side prevents Emotion to be RSC compatible. It seems to work fine: https://github.com/oliviertassinari/test-theme/blob/main/src/app/about/page.tsx at the condition of not supporting theme nesting in RSC. |
The problem
I would like to have a Next.js 13
Layout
component (eg.RootLayout
) that is a Server Component, and have my styling for that layout also stay in Server Components (potentially even in the sameapp/layout.tsx
file). I only want to switch to a Client Component if there is some client-only features I'm using such asuseState
.This also aligns with the current guidance (as of Jan 2023) from the Next.js team to just leave everything a server component until you absolutely need a client component.
Proposed solution
It would be great if Emotion would be able to be used in React Server Components (without conversion to a Client Component)
Alternative solutions
'use client'
every time that a page should be styledAdditional context
Moved from this other issue about Next.js 13
app/
directory support:The text was updated successfully, but these errors were encountered: