-
-
Notifications
You must be signed in to change notification settings - Fork 37
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
<GlobalStyles /> don't work properly with next.js app folder #182
Comments
Hello @yhaskell, I appreciate your diligent investigation into this significant bug that was previously unbeknownst to me. Your provision of the reproduction repository was particularly helpful. While I could attempt a quick fix from TSS, the optimal resolution would entail rectifying the root cause directly within the emotion repository. To facilitate this, could I kindly ask you to revise your repository to exclusively utilize @emotion/react? You can simply replace the existing code with the following:
"use client";
import React from "react";
import createCache from "@emotion/cache";
import { useServerInsertedHTML } from "next/navigation";
import { useState } from "react";
import { CacheProvider as DefaultCacheProvider } from "@emotion/react";
import type { Options as OptionsOfCreateCache } from "@emotion/cache";
import type { EmotionCache } from "@emotion/cache";
import type { ReactNode } from "react";
export type NextAppDirEmotionCacheProviderProps = {
/** This is the options passed to createCache() from 'import createCache from "@emotion/cache"' */
options: Omit<OptionsOfCreateCache, "insertionPoint">;
/** By default <CacheProvider /> from 'import { CacheProvider } from "@emotion/react"' */
CacheProvider?: (props: {
value: EmotionCache;
children: ReactNode;
}) => JSX.Element | null;
children: ReactNode;
};
export function NextAppDirEmotionCacheProvider(
props: NextAppDirEmotionCacheProviderProps
) {
const { options, CacheProvider = DefaultCacheProvider, children } = props;
const [{ cache, flush }] = useState(() => {
const cache = createCache(options);
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
key={cache.key}
data-emotion={`${cache.key} ${names.join(" ")}`}
dangerouslySetInnerHTML={{
"__html": styles
}}
/>
);
});
return <CacheProvider value={cache}>{children}</CacheProvider>;
}
"use client";
import React from "react";
import * as reactEmotion from "@emotion/react";
import type {
CSSInterpolation
} from "@emotion/serialize";
export function GlobalStyles(props: { styles: CSSInterpolation }) {
const { styles } = props;
return <reactEmotion.Global styles={reactEmotion.css(styles)} />;
} Please ensure that only the code necessary for reproducing the bug remains. You can refer to the @emotion/react documentation here. Please steer clear of the native css prop as it presents a challenging setup. Regrettably, I currently lack the bandwidth to undertake this task myself, but I am here to assist should you encounter any obstacles during the repository conversion. If solely using @emotion/react resolves the issue, it's excellent news as it would imply an error on my end that I can address. Conversely, if the problem persists, we'll proceed to open an issue in the emotion repository. If a solution isn't reached within a week, I'll personally intervene to rectify the situation. Please feel free to share any suggestions or thoughts you may have. I extend my deepest apologies for the less-than-ideal developer experience and sincerely hope that this hasn't consumed excessive hours of your time. Best regards, |
I've managed to reproduce it using only the |
@yhaskell Cool! That mean we can fix it quite easily. |
I'm trying to implement a fix and release a candidate |
I'm releasing 4.8.7-rc.0 right now. If you are right in your diagnostic, it should fix it 🤞🏻 |
It's fixed, thanks a lot for your help! |
Hello and thanks for an amazing project ;)
I discovered that the GlobalStyles component's current implementation doesn't work with the next.js app folder.
I've created a reproduction case here: https://codesandbox.io/p/sandbox/nifty-glitter-hvkpmw
The styles get added, but they are not updated when the styles parameter changes.
In the current example, when the dark mode switch is activated, the new styles are added, but the original ones stay in the head list and as a result the dark mode doesn't work :)
The "magic" button removes the block with the global css. But, as this block also contains non-global css for the primary text, when we click the button. those styles are being lost.
The text was updated successfully, but these errors were encountered: