The Correct Way To Use Fontawesome Icons in Gridsome

This a guide on how to integrate the Free Fontawesome Icons to Your Gridsome Project using npm. Fontawesome behaves strangely when you import it in the default manner. This guide shows you how to use Fontawesome, while avoiding the pitfall.

05/10/2020

Introduction

Integrating Fontawesome in regular Vue is simple and doesn’t really need extra tweaking. You just follow the instructions given on the official fontawesome-vue GitHub Page. However, integrating it into Gridsome requires an extra step.

Lets begin.

Installation

1. Install gridsome cli and live-server

npm i -g gridsome live-server

2. Create Project

gridsome create my-project

3. Install Fontawesome

npm i --save @fortawesome/fontawesome-svg-core @fortawesome/free-solid-svg-icons @fortawesome/vue-fontawesome@2

Setup

  • Import the fontawesome component and register it as ‘AppIcon’.
  • Import the compass, directions, sign, street view and traffic lights icon. Then register them using the library object.
// main.js

import DefaultLayout from "~/layouts/Default.vue";
import {
  faCompass,
  faDirections,
  faSign,
  faStreetView,
  faTrafficLight,
} from "@fortawesome/free-solid-svg-icons";
import { library } from "@fortawesome/fontawesome-svg-core";
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";

export default function (Vue, { router, head, isClient }) {
  library.add(faDirections, faTrafficLight, faStreetView, faSign, faCompass);

  Vue.component("Layout", DefaultLayout);
  Vue.component("AppIcon", FontAwesomeIcon);
}
  • Go to index.vue and add the code below. This is for demonstration purposes.
// index.vue

<template>
  <Layout>
    <div class="home">
      <app-icon icon="directions" size="lg"></app-icon>
      <app-icon icon="traffic-light" size="lg"></app-icon>
      <app-icon icon="street-view" size="lg"></app-icon>
      <app-icon icon="sign" size="lg"></app-icon>
      <app-icon icon="compass" size="lg"></app-icon>
    </div>
  </Layout>
</template>

<script>
export default {
  metaInfo: {
    title: "Hello, world!",
  },
};
</script>

<style lang="scss">
.home {
  display: grid;
  grid-template-columns: 1fr 1fr 1fr;
  & > * {
    margin: 2rem;
  }
}
</style>
  • Now build the project. gridsome build
  • This will generate the required static files and put them in dist/
  • Now serve the dist folder using live-server. liver-server dist/
  • Live-server will open your default browser and serve you the dist folder.
  • If you were keen, you will have noticed that the icons were HUGE for a slit second before returning to their normal size.
  • If you didn’t catch it, we can artificially slow things down by disabling cache and throttling the network speed in the Network Tab. This is illustrated in the video below 👇🏾. (NB: Don’t forget to enable cache after this)

youtube:https://youtu.be/1U9LCh0cfD0

What’s The Problem

The problem is that the Fontawesome CSS classes aren’t being injected into the HEAD tag of the index.html at build time. They are, instead, being served from the javascript when the site is opened in the browser.

This means that the large icons you see on first load are the raw SVG icons before any styling has been applied. Its only when the javascript has kicked in and the CSS class injected to the HEAD tag, that the icons return to the size the developer specified.

This is not the regular behaviour of Fontawesome. Normally, Fontawesome injects the CSS classes for us at build time. This is how it works in a Vanilla Vue and Angular project. This is possibly a bug.

Luckily, there’s a solution.

Solution

The solution is to:

  1. Firstly, disable the auto-inject CSS functionality in Fontawesome. You do this by importing the Fontawesome config and disabling it from there.
  2. Lastly, import the required styles manually. You can import it directly into your main.js or import it into your main SASS stylesheet.
// main.js

import DefaultLayout from "~/layouts/Default.vue";
import {
  faCompass,
  faDirections,
  faSign,
  faStreetView,
  faTrafficLight,
} from "@fortawesome/free-solid-svg-icons";
import { library, config } from "@fortawesome/fontawesome-svg-core"; // import the Fontawesome Config
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";

config.autoAddCss = false; // Disable auto inject

import "@fortawesome/fontawesome-svg-core/styles.css"; // Manually import the Styles

export default function (Vue, { router, head, isClient }) {
  t;
  library.add(faDirections, faTrafficLight, faStreetView, faSign, faCompass);

  Vue.component("Layout", DefaultLayout);
  Vue.component("AppIcon", FontAwesomeIcon);
}

The Result is illustrated in the video below 👇🏾.

youtube:https://youtu.be/-ZDTm8S-nxA

Now everything should work.

Conclusion

This guide has shown you how to correctly use Fontawesome in Gridsome correctly. Happy coding 🙂.

References