emotion-js / emotion

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

document is not defined #3196

Open stepan662 opened 1 month ago

stepan662 commented 1 month ago

Current behavior:

In some environments, checking for typeof HTMLElement !== undefined might not be enough, when accessing document.

We use emotion in @tolgee/ngx in a dev tools dialog (which is in react). However when using this package in angular 17 SSR, it fails, because it's trying to access document.

https://github.com/emotion-js/emotion/blob/fc74beeef5d71b366cd167846c5cd21a66826aa0/packages/react/src/context.js#L15

To reproduce:

https://stackblitz.com/edit/fuck-yeah-angular-ssr-1e3ut7

Seems like in angular SSR environment document is undefined, but HTMLElement is not, which is causing the issue.

Expected behavior:

I think this check should be more robust e.g typeof document !== 'undefined' && typeof HtmlElement !== 'undefined'. We are not actually rendering anything using emotion, it's just a part of the package, but since createCache is called immediately when we import the file.

If I replace this check with typeof HTMLElement !== undefined && typeof document !== undefined, it is resolved.

Environment information:

Andarist commented 1 month ago

Seems like in angular SSR environment document is undefined, but HTMLElement is not, which is causing the issue.

This is a bizarre environment. Why does it work like that?

stepan662 commented 1 month ago

I can't really tell you 😄

Andarist commented 1 month ago

To assess this issue I need to know, at the very least, where this HTMLElement is coming from in this implementation

stepan662 commented 1 month ago

I'm not an angular expert, but I think it works like this because angular is using html element class for rendering, so it needs to have this primitive available on SSR. And it doesn't need the whole document.

stepan662 commented 1 month ago

I think it's kinda not correct to check typeof HTMLElement !== 'undefined' and then touch the document, it would make more sense to check the document itself. (Not sure if there is some reason why it's done like this).

Andarist commented 17 hours ago

Could u check if the new version works in this context?