-
-
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
Plans to support Next.js 13 - /app directory #2928
Comments
It might be possible see about circling the wagons with the MUI and Vercel teams, as well, on this. MUI is very widely used (and teams are paying!). I am not sure what the specific numbers are, but I have to imagine we have a very large contingent of MUI/Emotion users overlapping with Next.js. Having these two titans not work together is a miss. (I suspect if getting this working needed some sponsorship, $$$ could be found!) |
We’re also super looking for this so Theme UI can support the app directory! |
We may want to add an explicit API for this but this works today: // app/emotion.tsx
"use client";
import { CacheProvider } from "@emotion/react";
import createCache from "@emotion/cache";
import { useServerInsertedHTML } from "next/navigation";
import { useState } from "react";
export default function RootStyleRegistry({
children,
}: {
children: JSX.Element;
}) {
const [cache] = useState(() => {
const cache = createCache({ key: "css" });
cache.compat = true;
return cache;
});
useServerInsertedHTML(() => {
return (
<style
data-emotion={`${cache.key} ${Object.keys(cache.inserted).join(" ")}`}
dangerouslySetInnerHTML={{
__html: Object.values(cache.inserted).join(" "),
}}
/>
);
});
return <CacheProvider value={cache}>{children}</CacheProvider>;
}
// app/layout.tsx
import RootStyleRegistry from "./emotion";
export default function RootLayout({ children }: { children: JSX.Element }) {
return (
<html>
<head></head>
<body>
<RootStyleRegistry>{children}</RootStyleRegistry>
</body>
</html>
);
}
// app/page.tsx
/** @jsxImportSource @emotion/react */
"use client";
export default function Page() {
return <div css={{ color: "green" }}>something</div>;
} |
@mitchellhamilton did you get this working for you? Trying in a StackBlitz just now, it seems like it's giving me an error about
It does seem to work if the layout component is made into a client component, but this would be unfortunate: |
Oh it seems like my optimization of removing the Working StackBlitz, based on @emmatown's original example: |
Reported a bug about the SWC Emotion transform plugin here: |
Just note that the presented solution works with the app directory - it still doesn't quite work with streaming. It's not exactly Emotion's fault though, other libraries won't work either because the callback provided to You can observe this on this stackblitz that uses Styled Components. I've prepared it by copy-pasting the example from the Next.js docs, on top of that I've just added a single Suspense boundary to "chunk" the stream. The rendered |
Thank you all so much for the samples & explanation! @Andarist, could you give a little more color on the long-term situation here? If Next resolves the SWC bug & Emotion does an update, where will that leave us with server component support? Are there aspects that are never going to work? |
To the best of my understanding - we should be able to support server components in the future. Some parts of that are fuzzy to me though. Mainly I'm not sure how to avoid injecting the same styles back to the client on server component refetches. We rely on a list of inserted IDs but server components render for a particular request - where we don't have access to the IDs inserted by previous requests (or by the client, for that matter). |
I too need Mui + emotions to work, this would greatly speed my migration to client/server component architecture |
As of right now, I converted all the components into client components to ‘migrate’ to nexjs13. 😂 Need this before any meaningful migration |
@mitchellhamilton Is cache.compat something exclusive to Emotion 10? |
Have you found any solutions yet? if you have can we kindly get a timeline for emotion-js working with nextjs13 |
@godfrednanaowusu I ported a next 12 project to next 13 and have not had any trouble with emotion and mui working correctly (besides a breaking change in next/link). The issues here appear to be about using the Essentially by asking to use the react 18 features with |
@MinervaBot read the title, the issue is about nextjs 13 app directory, not just upgrading and use pages folder |
@unfernandito I noticed a lot of people were talking about needing this to use 13, which seemed to perhaps deserve some clarification, since |
After talking with the Next.js team and helping them recognize the problem with With that fix Emotion roughly works in the "use client";
import { CacheProvider } from "@emotion/react";
import createCache from "@emotion/cache";
import { useServerInsertedHTML } from "next/navigation";
import { useState } from "react";
export default function RootStyleRegistry({
children,
}: {
children: JSX.Element;
}) {
const [{ cache, flush }] = useState(() => {
const cache = createCache({ key: "my" });
cache.compat = true;
const prevInsert = cache.insert;
let inserted: string[] = [];
cache.insert = (...args) => {
const serialized = args[1];
if (cache.inserted[serialized.name] === undefined) {
inserted.push(serialized.name);
}
return prevInsert(...args);
};
const flush = () => {
const prevInserted = inserted;
inserted = [];
return prevInserted;
};
return { cache, flush };
});
useServerInsertedHTML(() => {
const names = flush();
if (names.length === 0) return null;
let styles = "";
for (const name of names) {
styles += cache.inserted[name];
}
return (
<style
data-emotion={`${cache.key} ${names.join(" ")}`}
dangerouslySetInnerHTML={{
__html: styles,
}}
/>
);
});
return <CacheProvider value={cache}>{children}</CacheProvider>;
} (kudos to the @emmatown for providing this implementation) We need to figure out the exact APIs for handling this within Emotion but conceptually the thing would end up being very similar - you just won't have to override Note that you should only use Emotion with the so-called client components (we might add |
MUI Next.js examples are now using the integration package, see mui/material-ui#40199. |
@francoisjacques I have create a public Repo with the minimal version I used: https://github.com/tom-streller-tutti/minimal-nx-nextjs-emotion-mui It's not exactly minimal, as it also contains |
@tom-streller-tutti fyi: what you mention in your rant readme is kind of what mui did a while ago on all components they export. ps. das logo kenn ich, gruess us züri :) mui/material-ui@a4afa9f#diff-404207b76c551306dc4629e283a6483cd30cff95b811d3bd57147b5fabca3b79 |
As far as Material UI is concerned:
|
React 19 - to the best of my knowledge - is meant to allow using runtime CSS-in-JS libs in RSC. I'm playing with their Float APIs and it looks promising. |
The truth is it's not working well. I am keeping nextjs version to 12 because of this issues. I should have choose |
@bexoss you can use v13, just don't use app router but pages router. It's safer to be on the newer version probably:) |
@bexoss What issue did you experience? |
- emotion-js/emotion#2928 - the version of next.js over 13 was not supported emotion
- emotion-js/emotion#2928 - the version of next.js over 13 was not supported emotion
This is so sad. React moving to ssr and no serious support for real css encapsulation. And tailwind is so much going the very wrong direction. I love css and I hate the tailwind abstractions. I actually really consider going back to global css style bundles or post css imports. For a graphic background person like me this is such a drag. Other frameworks like angular and web components have made much better moves keeping some sort of real encapsulation possible as suggested by W3C |
there are plenty of new css in js solutions |
Yeah, but all those solutions that implement static extraction constitute a massive downgrade in DX and expressiveness compared to dynamic styles. Being able to define your styles based on the component states, props, and ambient theme is very powerful. I mean, sure, a solutions like Griffel and tss-react does look the same on the surface, but Griffel comes with serious limitations that tss-react or Emotion does not have. |
@denu5 thanks for the hints. I was researching a little and since I usually am super sceptical when switching tech, none of the things I found convinced me. Linaria looks fun, because I can almost write css as it is supposed to. @garronej But hey, emotions was also just a work around for something I was so used to from dart and polymer and webcomponents and even angular. Actual shadow and shady dom :-) I like that you mention expressiveness and the lack thereof. Yes, I think css is a super expressive language and it's poetry. I do this for 25 years since I was a teenager and it's my way of describing the world. It's even more my language than English. It's part of my dna. So perhapse I am biased haha but it is hard enough to change my grammar every 6 months in the web anyhow. (Insert Frontend dev laugh) |
Does Do we need to follow these steps to enable it: https://nextjs.org/docs/app/building-your-application/styling/css-in-js#configuring-css-in-js-in-app ? Does anyone have an example of doing so? By default it does not seem supported, even with jsx pragma at top of file:
Thank you. |
- emotion-js/emotion#2928 - emotion이 next app router 계속 미지원이라서 변경
Hi! Is there any news about this topic? |
The problem
Next JS just release their v13 publicly.
As seen in their docs,
emotion
has not yet added support.Is there any plan to add support in the near future?
Thanks.
The text was updated successfully, but these errors were encountered: