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 |
@dcruzb @schoenwaldnils that's probably because you are not leveraging server components.... so all your components just work as if your were using the pages directory |
So let summary, here is how I dealing with this isssue. First in tsconfig.json try to put Next if you are using Server component put /* @jsxImportSource react */ in the top of the file. It's a workaround for my project now , hope there some solution better. |
Still not working with version 14? |
For those trying to combine Next JS, Material UI and custom styles (with Tailwind, CSS Modules, etc.), MUI has released the I was trying the previous integration instructions for the App Router (Next JS I guess that the source code of the package may have precious insights for other scenarios trying to combine Next JS and Emotion without Material UI as well.
|
Anybody from MUI or community working on an updated version of the next/mui example? https://github.com/mui/material-ui/tree/master/examples/material-ui-nextjs-ts |
This appears still to be an issue with NextJS 14.0.2 and Emotion v11. Reading through the comments above and trying a minimally viable project to verify, I concluded that the following is necessary to get
However, all React Server Components only work if they have the pragma The pragma tells Babel/TypeScript/SWC to use the default The emotion JSX constructor appears to generate code that uses This might be fine for a small project, a new green field project, as it's just something to keep in mind. The issue we are facing is that we want to migrate a large codebase to Next.js 14's My suggestions for fixing this issue with a) Add the required I do not know how feasible either of these solutions are, as I'm unfamiliar with how Emotion works internally. My only other tip for whoever ends up here to read this is to consider a different CSS framework for your new project. Even if the above issue is solved, the inherent issue with emotion appears that it's not compatible with how RSCs are intended to be rendered, so that most optimisations you expect to get from using them (like the VDOM not being as large and hydration times being lower) will not manifest when all your components are client components by necessity. |
Thank you @tom-streller-tutti! Is your minimal experiment something that can be shared for other to look at? It could be useful to create a "safe" boilerplate for others to use... for those who can't consider using a different styling engine than emotion for various reason. |
Following this thread, since our stack is also Next.js + Emotion + MUI and currently migrating from Next.js 12 to 14 I just tried adding |
For people trying to make the Next + Emotion + MUI combination work in Next 14, have you tried with |
Do you get it even when you disable turbo? |
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
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: