The style of a div using only gradient background class worked fine on dev, but not on prod. And when adding another class (text-white here), then it works:
<div tw="bg-gradient-to-b from-red-500 to-gray-400"><div tw="bg-gradient-to-b from-red-500 to-gray-400 text-white">If you want to try, go the the sandbox link above. I found a way to test on dev and on prod, by changing the dev command in the package.json. When you first launch, the dev command will be set on next dev. If you want to see the issue, change the dev command to next build && next start:
next dev
next build && next start
Does anyone have any idea why?
Hi,
The problem seems to come from the emotion cache / SSR configuration.
I think you can either:
CacheProvider in _app.js (the style will be added by emotion in the body of the page):import { GlobalStyles } from "twin.macro";
const App = ({ Component, pageProps }) => (
<>
<GlobalStyles />
<Component {...pageProps} />
</>
);
export default App;
_document.js to extract the generated style in the head of the document. Here is an example CodeSandbox with this fix: https://codesandbox.io/s/nifty-http-9puxjThanks for the quick answer!
Both options did work for me. Which of the 2 would you recommend?
Also, for the first option, what impact does it have on the app to remove CacheProvider?
Hi,
You can find more information on this topic in the emotion docs: https://emotion.sh/docs/ssr.
I would suggest using the default approach if your project does not require the advanced approach. It provides better performance (with response streaming) and is easier to maintain. Also, most of its limitations can be worked around.
In the first approach, @emotion/react will create the CacheProvider under the hood and use it in every Emotion component, so it should have no impact on your application.
Ok thank you for the detailed answer!
In the first approach,
@emotion/reactwill create theCacheProviderunder the hood and use it in every Emotion component, so it should have no impact on your application.
Hey @Dramloc thanks for the response here, I've added the advanced method to avoid the flash of unstyled text. I haven't tested the other method yet but does that also fix it? If so, do you think it's worth updating the twin starter to use that method?
Hey @ben-rogerson,
The default emotion approach fixes this issue but after testing it on a larger example, I had some problems with it.
Utilities like space-* and divide-* use the CSS sibling combinator (e.g.: :not([hidden])~:not([hidden])) and can cause layout shifts with this approach.
While testing this, I also found that some issues still remain with the advanced approach. Emotion seems to sometime create invalid CSS when serializing the style with stylis (see https://github.com/thysultan/stylis.js/issues/250). This issue can happen when the last declaration of a style is a CSS variable.
For example, in this snippet:
<span tw="ring-inset" />
<div tw="p-4" />
The ring-inset utility _will_ be applied but the next CSS declaration (p-4) will be skipped by the browser.
In practice, this can cause a FOUC but it's less frequent and less noticeable than the layout shifts of the default approach.
I think you can keep the twin starter as it is and wait for the bug fix on stylis.
Thanks for letting us know about that bug, sounds like a doozie. Hope it's fixed up soon, I'll be keeping an eye out for it.