emotion-js / emotion

👩‍🎤 CSS-in-JS library designed for high performance style composition
https://emotion.sh/
MIT License
17.51k stars 1.11k forks source link

FOUC when using emotion with prepend true and Next.JS app dir #3059

Open kpericin opened 1 year ago

kpericin commented 1 year ago

Current behavior: When using prepend: true with the code snippets from https://github.com/emotion-js/emotion/issues/2928, there is FOUC. On the server, emotion styles are always injected before any other CSS which causes style overrides to not be applied.

To reproduce: https://github.com/kpericin/mui-next-appdir-demo/tree/emotion-prepend (or https://stackblitz.com/edit/stackblitz-starters-qmdyic?file=app%2Flayout.tsx if that's easier).

Overridden component is in https://github.com/kpericin/mui-next-appdir-demo/blob/emotion-prepend/shared/AppButton/AppButton.tsx

Expected behavior: Based on comments in https://github.com/emotion-js/emotion/issues/2928 I got the impression that emotion works with app dir as long as components styled using it have "use client" directive. Is there a way to get prepend to work with app directory?

Environment information:

garronej commented 1 year ago

Hi @Andarist,

What @kpericin is trying to do is something I don't have a solution for. He's using css modules and he want to ensure that the emotion style are injected before so that he's CSS take precedence over emotion generated style.

In the page router version of the TSS tooling I'm able to implement some magic to get prepend working.

https://github.com/garronej/tss-react/blob/d193e1176019427650f3b9e7ca837b2845cef481/src/next/pagesDir.tsx#L106-L108

Unfortunately, with the App Router, I don't know how to do it or even if it's possible. We're relying on the useServerInsertedHTML hook and I don't know how to configure it to provide a precise insertion point...

Related issue in the TSS repo.

Thanks you in advance for your insight.

kpericin commented 1 year ago

I managed to find a workaround which seems to be good enough for my use case, although it may not be acceptable for everyone.

If emotion styles are wrapped into @layer, all other styles which aren't in a layer will take precedence. Here is stackblitz and github branch.