External component libraries using emotion not rendering styles on first load

In my project I have an external component library I use for quite a few parts of my site. I recently refactored this to use emotion CSS in JS and it has been working nicely in all other projects that use it, however in Frontity I am getting a strange issue with styles on initial load.

When the page first loads my components, none of the emotion injected styles are active on the components, and then after a second they apply. I don’t know how else to describe the issue as no errors occur.

You can see the issue by visiting this link and hard refreshing a few times: https://gfw-blog-headless-e1nmpzhhg.now.sh/

This library is working fine in other SSR and none SSR apps using the global styles and regular components. Could this be due to the fact frontity does its own thing with emotion?

Any thoughts would be very welcome!

Hi @e.j.a.brett, thanks for your question.

This effect is known as a flash-of-unstyled-content (FOUC) issue, and it’s indeed related to the use of CSS-In-JS and emotion

Can you share a repo with the code of your project so we can test it and check what may be causing this issue in your project?

Hi @juanma thanks for getting back to me! The project is in this repo: https://github.com/Vizzuality/gfw-blog-headless/tree/feature/update-gfw-components. You need to checkout the branch feature/update-gfw-components which is having the issue.

The components that are having issues are those imported from our components library here: https://github.com/Vizzuality/gfw-components which is also built with emotion.

Let me know if I can provide anything else.

Hey @e.j.a.brett! :wave:

This is Michal from the Frontity team. I ll have a look at this issue tomorrow and will let you know if I need any more information. Cheers! :slightly_smiling_face:

1 Like

Great! Thank you for taking the time!

Hi @e.j.a.brett

I"m sorry but I was not able to run your project.

I checked out the feature/update-gfw-components branch like you mentioned earlier, ran installed dependencies and ran npm run dev.

The app fails with:

ReferenceError: document is not defined
    at A (webpack-internal:///./node_modules/gfw-components/dist/bundle.js:1:593210)
    at p (webpack-internal:///./node_modules/gfw-components/dist/bundle.js:1:594492)
    at u (webpack-internal:///./node_modules/gfw-components/dist/bundle.js:1:593147)
    at LboF.e.exports (webpack-internal:///./node_modules/gfw-components/dist/bundle.js:1:594830)
    at Object.Ut/D (webpack-internal:///./node_modules/gfw-components/dist/bundle.js:1:931367)
    at r (webpack-internal:///./node_modules/gfw-components/dist/bundle.js:1:124)
    at Object.Z5cx (webpack-internal:///./node_modules/gfw-components/dist/bundle.js:1:1017304)
    at r (webpack-internal:///./node_modules/gfw-components/dist/bundle.js:1:124)
    at Object.FT44 (webpack-internal:///./node_modules/gfw-components/dist/bundle.js:1:444996)
    at r (webpack-internal:///./node_modules/gfw-components/dist/bundle.js:1:124)

So, it looks like you are referring to document in the your component library and it’s failing while doing server side rendering. I did a quick search on github and looks like you are referring to document in a couple of places in the component library without checking first that document exists: https://github.com/Vizzuality/gfw-components/search?q=document&unscoped_q=document

Ah I am sorry you ran into issues! I took a look and the reason for the error is we use yarn with a yarn-lock so when you ran npm i you installed more recent versions of the lib which seem to have caused this issue. gfw-components has two methods for being installed, one as a normal npm module, and another as a script that gets injected into the document (for non react sites). These two bundles lives completely separately so I will see what is going on with the document error. It should not be present in that built at all.

I have pushed a commit to fix the version of this lib to an older one which should remove any document references and allow you to work with npm instead of yarn.

If you still have the patience do you think you would be able to try again? :sweat_smile:

Thank you for taking the time.

Hey @e.j.a.brett, no problem, I was able to pull and run the project again this time with no issue :slight_smile:

I can see that the styles are not attached to the <head> on the server because I receive the initial HTML without the styles.

However, I didn’t find a moment to look into it in depth today and troubleshoot this so you’ll have to bear with me a little longer :sweat_smile:

Hi @e.j.a.brett,

I took another look at this and I can see that some of the styles are attached on the server, however, some of them are missing.

For example I can put the breakpoint here:

And dump the HTML from the html variable into a file. I can see that the there are some CSS classes referred in the html, e.g. .css-ap9cid-RowDiv that do not have the declarations in the CSS.

@luisherranz Do you have any more insight on this by any chance?

Thanks for taking a look! Yes, it appears that any styles loaded by emotion from my external components library are not added on the server, and the ones in frontity are. That css class .css-ap9cid-RowDiv for example comes from my component library that is made with emotion.

They are added when the client first renders which causes the flash. Would this be caused by frontity managing the import of styled and css from its own package? import { styled, css } from 'frontity'?

that’s all true, unfortunately :slight_smile:

This was my thought as well - that perhaps this is not compatible with how you define the externals in you webpack configuration https://github.com/Vizzuality/gfw-components/blob/master/webpack.config.js#L106