FortAwesome / vue-fontawesome

Font Awesome Vue component
https://fontawesome.com
MIT License
2.39k stars 133 forks source link

Make this component better for SSR #86

Open meteorlxy opened 6 years ago

meteorlxy commented 6 years ago

I'm using SSR to prerender a page into a static HTML file (Vuepress)

Our FontAwesomeIcon can be prerendered, but not so perfect.

At the first glance when opening the page, it looks like this:

image

After the scripting, it display well:

image

The first glance is really annoying, so currently, I hacked our component to avoid being prerendered:

import FontAwesomeIcon from '@fortawesome/vue-fontawesome'
Vue.component('FontAwesomeIcon', {
    functional: true,
    props: FontAwesomeIcon.props,
    render (h, context) {
      if (context.parent._isMounted) {
        return h(FontAwesomeIcon, context)
      } else {
        context.parent.$once('hook:mounted', () => {
          context.parent.$forceUpdate()
        })
      }
    }
  })

The cause of this issue is that the <style> is injected by js script, so only after scripting will it display well. (Could not be extracted by ExtractTextPlugin)

If we can put the styles into our component's <style> section, like some other vue components, then it could be extracted correctly.

robmadole commented 6 years ago

@meteorlxy the reason the icon is large is due to the fact that the styles are not loaded (I'm sure you've probably already figured this out.)

What we'll probably end up doing is supporting a mode where all styles are inlined on the rendered SVG.

robmadole commented 6 years ago

Oh, also note that we include the CSS in node_modules/@fortawesome/fontawesome/styles.css for the @fortawesome/fontawesome package. If you are using the newer pre-release version it's available in the same location.

meteorlxy commented 6 years ago

@robmadole Oh, thx. Importing node_modules/@fortawesome/fontawesome/styles.css manually could be a temporary solution.

dariuszlorek commented 6 years ago

That's still unresolved. @robmadole think about some way to fix it.

robmadole commented 6 years ago

@dariuszlorek we know how to fix it. Just haven't done the work yet ;)

Krystus commented 6 years ago

@robmadole hey... come one. We are waiting. 😆

alexbudure commented 6 years ago

@robmadole Any updates on this? 😄

robmadole commented 6 years ago

No update yet. It is still in the list.

Krystus commented 6 years ago

@robmadole anything?

moltar commented 6 years ago

Just ran into this too, and took me several hours to figure out the chain.

When using Nuxt and generate mode, then viewing the page without JS this also becomes a problem. Disabling JS = disables injected CSS.

But a flash of unstyled icons is a bit annoying too.

moltar commented 6 years ago

Can fix the above problem by loading styles manually:

import "@fortawesome/fontawesome-svg-core/styles.css"
meteorlxy commented 5 years ago

@robmadole Has this been solved?

robmadole commented 5 years ago

If you are using a Nuxt.js-based project we've got a good solution:

https://github.com/FortAwesome/vue-fontawesome#nuxtjs

Does that solve it for you @meteorlxy ?

meteorlxy commented 5 years ago

Hmmmm, I see.

I'm not using Nuxt.js, but is that means we still need to import '@fortawesome/fontawesome-svg-core/styles.css' manually ?

From my point of view, I don't think there are any differences from the discussion above 😕

achaphiv commented 5 years ago

You could create a transparent wrapper component to scope the CSS:

<template>
  <FontAwesomeIcon v-bind="$attrs" v-on="$listeners" />
</template>

<script>
import { FontAwesomeIcon } from '@fortawesome/vue-fontawesome'
import { config } from '@fortawesome/fontawesome-svg-core'

config.autoAddCss = false

export default {
  components: { FontAwesomeIcon },
  inheritAttrs: false
}
</script>

<style scoped>
@import 'node_modules/@fortawesome/fontawesome-svg-core/styles.css';
</style>
robmadole commented 5 years ago

I haven't looked at Vuepress but I think the best solution is going to be importing that '@fortawesome/fontawesome-svg-core/styles.css' file. I've considered a couple of other options but they have some downsides that I'm not quite sure how to work around yet. So we are trying to see how far we can get with that styles.css file in these different tools.

@meteorlxy if you can figure out a way to do it with Vuepress and summarize it here I'll add some docs in the main README.md. And re-opening since I kinda killed this prematurely (I thought Vuepress just used Nuxt.js)

samanthaming commented 4 years ago

@robmadole I'm currently using VuePress on my site and I think I got a fix. Just wanted to share my solution in case others are also searching for this 🙂

enhanceApp.js

import { config } from '@fortawesome/fontawesome-svg-core';

config.autoAddCss = false;

And then add the fa style in either inside your styles folder (I'm using stylus, but it should also work for scss files)

@import '~@fortawesome/fontawesome-svg-core/styles.css';

OR in your vue component .vue

<style>
  @import '~@fortawesome/fontawesome-svg-core/styles.css';
</style>