5
votes

I have a vue.js app and it's bundled with webpack. I use the vue-server-renderer to render it on the server side. Everything works great there. In my webpack config i am using using the ExtractTextPlugin:

new ExtractTextPlugin({
  filename: `css/[name]${isProduction ? '.[hash]' : ''}.css`,
  allChunks: true
})

If i use allChunks: true then i get a single css file an everything works. But in a big application that is not ideal. Now i have a bunch of CSS that is loaded and not being used on the page.

If I set allChunks: false then I get a smaller initial file and the css for the current component is injected into the head on page load. This is almost what i want. But the problem here is if you are using SSR then you get the initial HTML in the page with no CSS, then when CSS loads everything gets rendered correctly.

What i would like is during my SSR rendering functions i could get access to CSS for the current page and inject it into the head myself before returning to browser.

I have tried to build a webpack loader, but i don't think this is right, and i had problems integrating with css-loader.

I think it should be either an issue with vue-loader or vue-server-renderer. Not really sure where to go from here. So i guess i am looking for some guidance, has anyone else figured this out, or can point me to the right direction.

1

1 Answers

0
votes

This is is somewhat hacky (IMO) but I recently did something similar on the client side where I need to replace a:hover CSS with color values from the Vuex store (as you may know pseudo selectors can't be changed with JS alone).

You can create a component that sets styles directly in Vue with JavaScript values, or in your case, you could just replace the CSS with what you're pulling from the ExtractTextPlugin.

In your JavaScript file declaring Vue:

Vue.component('v-style', {
  render: function (createElement) {
    return createElement('style', this.$slots.default)
  }
})

In a Vue component:

<v-style>
  a:hover {
    color: {{ colors.hover }}
  }
</v-style>

I would imagine this will render find on the server side but I haven't tried it. I assume you could replace the a:hover part of the above code with your style declarations. It won't be in head but I don't imagine that should matter?

Taken from this SO answer: https://stackoverflow.com/a/54586626/895091