Ante Sepic - Personal blog

Server rendering emotion with Nuxt

November 15, 2018

I have had a few flings with CSS-in- JS so far but never anything serious, but this week I decided to commit to using emotion in my side project. I am using Nuxt and have written all of my styles with emotion (well, all except the global ones, which I decided to load from an external stylesheet).

It all went reasonably well, until I tried to generate my website for production (using nuxt generate). And there it was, the infamous FOUC, or flash of unstyled content. Turns out that emotion will not automatically output the css needed for the components out of which the initial view is composed, it only outputs them on the client side, resulting in a brief flash.

After hours of searching, I managed to solve it:

First of all, npm install the emotion-server package: npm install --save emotion-server

Then, require it in your nuxt.config.js file: const { renderStylesToString } = require ('emotion-server');

This will allows us to use a very cool function renderStylesToString which takes HTML and inlines the CSS necessary for each component before it is needed. We now just need to hook into a nuxt hook that will allows us to modify the HTMl response from the server.

Here is what those might look like (added to the object you are exporting from your nuxt.config.js file):

    hooks: {
      render: {
        route (url, result) {
          const withCss = renderStylesToString (result.html);

          result.html = withCss;
        },
      },
      generate: {
        page (page) {
          const withCss = renderStylesToString (page.html);

          page.html = withCss;
        },
      },
    },

I am using two different hooks because I am statically exporting my website, and a render hook is not called with nuxt generate.

That’s it! I have lost too much time finding this, so now it’s here, ready to save the next person some time :)

Bonus hint: Due to the way renderStylesToString inserts the CSS, you should avoid using :first-child , :nth-child() etc. in your css as all those style tags in your HTML might cause a flash once they are hydrated on the client and moved to the <head>.


Ante Sepic

Hello and welcome to my personal blog. You probably ended up here because you have a problem you are trying to solve. I hope you'll be able to find a solution to it here. Good luck! Follow me on Twitter