How to: Use Font Awesome 5 in your Sage theme

Use Font Awesome 5 in a Sage 9 theme, loading SVGs via the advanced JavaScript API to take advantage of tree shaking.

(Tree shaking is a code optimization process that trims unused pieces from bundled assets. In other words, if you only use two icons, all the other ones will be removed when you run yarn build:production.)


If you just want to get Font Awesome up and running as quickly and easily as possible…
… then this method is not for you. Instead, load Font Awesome from their CDN and put the desired icons in your markup.


Install the packages

Install the core package (provides the functionality but not any icons):

yarn add @fortawesome/fontawesome-svg-core

And one or more icon sets, depending on which icons you want:

yarn add @fortawesome/free-solid-svg-icons
yarn add @fortawesome/free-regular-svg-icons
yarn add @fortawesome/free-brands-svg-icons
yarn add @fortawesome/pro-solid-svg-icons
yarn add @fortawesome/pro-regular-svg-icons
yarn add @fortawesome/pro-light-svg-icons

Want to use the pro packages? See the final section of this guide.

Set up the icons in your JavaScript

Wherever you prefer in your JS, import the needed modules. Unless you’re going to be using a lot of icons, it’s probably best to import the specific icons you’ll use.

For example, we’ll import the Facebook and Twitter icons in main.js:

// import then needed Font Awesome functionality
import { library, dom } from '@fortawesome/fontawesome-svg-core';
// import the Facebook and Twitter icons
import { faFacebook, faTwitter } from "@fortawesome/free-brands-svg-icons";

// add the imported icons to the library
library.add(faFacebook, faTwitter);

// tell FontAwesome to watch the DOM and add the SVGs when it detects icon markup
dom.watch();

You can also import an entire icon set at once, but that will result in a much larger bundle for your users to download. If you’ve thought through the performance implications and you have a good reason to do it anyway, see here.

Add the icon markup to your templates

In the appropriate template file:

<!-- Facebook icon -->
<i class="fab fa-facebook"></i>
<!-- Twitter icon -->
<i class="fab fa-twitter"></i>

Build

Finally, run yarn build.


Using the Pro Icon Sets

If you want to use the pro icon sets, you’ll need to set your authorization token. You can do this globally, so that it is available to all your projects, or locally, so that it is available for a specific project.

In both examples below, replace your-token-here with your actual auth token.

Globally

npm config set "@fortawesome:registry" https://npm.fontawesome.com/ \
npm config set "//npm.fontawesome.com/:_authToken" your-token-here

Locally
Add a .npmrc file to the root of your project with the following:

@fortawesome:registry=https://npm.fontawesome.com/
//npm.fontawesome.com/:_authToken=your-token-here

You can find both your token and more docs on using the pro version here. Note that this page of the docs is talking about a different method of using FontAwesome, so only pay attention to the instructions on adding your auth token.


Using Icons in Pseudo Elements

I don’t recommend it (and neither does Font Awesome), but if you can’t avoid it, see this post for quick instructions on getting Font Awesome working with pseudo elements. Be warned that this has caused various problems for users.


Related docs

30 Likes

That’s sweet man. Easier to use it than I expected it to be :slight_smile:
Thanks a lot.

1 Like

Well I do get “error ‘faFacebook’ is not defined no-undef
10:37 error ‘faTwitter’ is not defined no-undefstrong text

Not sure what I’m doing wrong.

@Bezelinja Can you confirm that you ran both yarn commands (to install the base package and the brands package) and they installed successfully? You should see these folders in your theme:

node_modules/@fortawesome/fontawesome
node_modules/@fortawesome/fontawesome-free-brands

And what JS file do you have the import code in? Can you share the code from that file?

Yep. Installed through yarn. Code is in main.js.

Maybe

// add the imported icons to the library
fontawesome.library.add(faFacebook, faTwitter);

should be in different file?

I have that in main.js as well:

// import external dependencies
import "jquery";
// base package
import fontawesome from "@fortawesome/fontawesome";
// Facebook and Twitter icons
import faFacebook from "@fortawesome/fontawesome-free-brands/faFacebook";
import faTwitter from "@fortawesome/fontawesome-free-brands/faTwitter";

fontawesome.library.add(faFacebook, faTwitter);

// Import everything from autoload
// prettier-ignore
import "./autoload/**/*"

// import local dependencies
import Router from "./util/Router";
import common from "./routes/common";
import home from "./routes/home";
import aboutUs from "./routes/about";

/** Populate Router instance with DOM routes */
const routes = new Router({
  // All pages
  common,
  // Home page
  home,
  // About Us page, note the change from about-us to aboutUs.
  aboutUs,
});

// Load Events
jQuery(document).ready(() => routes.loadEvents());

I just created a new theme and ran through the above process to confirm it, and it worked. The only thing I left implicit was running yarn build, but I’m guessing that’s when you’re getting the errors–is that correct?

1 Like

// base package
import fontawesome from “@fortawesome/fontawesome”;
// Facebook and Twitter icons
import faFacebook from “@fortawesome/fontawesome-free-brands/faFacebook”;
import faTwitter from “@fortawesome/fontawesome-free-brands/faTwitter”;

Now I put this code just under import jquery and it works. I must have been doing something wrong before.

Thanks a lot!

1 Like

How-to use fonts from the pro version:

yarn add @fortawesome/fontawesome
yarn add @fortawesome/fontawesome-pro-regular
# .npmrc
@fortawesome:registry=https://npm.fontawesome.com/FONTAWESOME-ACCOUNT-TOKEN
// main.js
import 'jquery';
import fontawesome from '@fortawesome/fontawesome';
import faBars from '@fortawesome/fontawesome-pro-regular/faBars';
import faTimes from '@fortawesome/fontawesome-pro-regular/faBars';

fontawesome.library.add(faBars, faTimes);
<!-- Blade template -->
<i class="far fa-bars"></i>
6 Likes

This is cool, @mmirus . Thanks a lot. Will try definitely try it out later today.

1 Like

How about using Font Awesome in pseudo elements?

Add this line after the imports:
fontawesome.config = {searchPseudoElements: true}

And the CSS:

&::before {
  content: "\f055";
  font-family: "Font Awesome 5 Solid";
  display: none;
}
3 Likes

I’ve been attempting to add the pseudo element support as you described here, @marcelo2605, but on every build I’m getting the unrecognized generic font error. Everything else is set up as above. Any thoughts?

@dplacey Check if you put fontawesome.config = {searchPseudoElements: true} after import icon and before fontawesome.library.add(..).

1 Like

I checked this just to verify and it works!

Yeah, just gave it another try… here’s that portion of the main.js:

// base package
import fontawesome from "@fortawesome/fontawesome";
// Facebook and Twitter icons
import faFacebook from "@fortawesome/fontawesome-free-brands/faFacebook";
import faTwitter from "@fortawesome/fontawesome-free-brands/faTwitter";

// add pseudo elements
fontawesome.config = {searchPseudoElements: true}
// add the imported icons to the library
fontawesome.library.add(faFacebook, faTwitter);

And then within my header.scss:

.menu-social li a::before {
  display: inline-block;
  font-family: "Font Awesome 5 Solid";
  line-height: 1;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
}

.menu-social li a[href*='facebook.com']::before { content: "\f09a"; }

.menu-social li a[href*="twitter.com"]::before { content: "\f099"; }

The markup method with the <i> element seems to work fine, but when I run yarn build it errors out—yarn run lint:stylesgives me the line for font-family: "Font Awesome 5 Solid";

I feel like I’m just missing something very obvious here.

Well it’s not really a solution, but I did stumble on something that seems to get it working:

With that same main.js setup, I’ve removed font-family: "Font Awesome 5 Solid"; from the styling, but added a font-size to it… now they seem to show up fine.

Odd stuff, but I suppose it makes sense.

Edit: More information for anyone working through a similar problem:

I’m using pseudo elements for a custom navigation implemented in header.blade.php with:

<nav class="menu-social">
    @if (has_nav_menu('social_navigation'))
        {!! wp_nav_menu(['theme_location' => 'social_navigation', 'menu_class' => 'nav', 'link_before' => '<span class="screen-reader-text">', 'link_after' => '</span>', 'fallback_cb' => false]) !!}
    @endif
</nav>

The other specific thing that seems to have gotten things working for me in this particular instance was including the class fa to the menu entries for that custom menu in the WordPress Dashboard itself. I haven’t dug in deeper to explain it completely but wanted to add that as part of it working successfully, now.

The markup method with the <i> element seems to work fine, but when I run yarn build it errors out—yarn run lint:styles gives me the line for font-family: "Font Awesome 5 Solid"; I feel like I’m just missing something very obvious here.

What stylelint error do you get? Sometimes it’s just the font-family-no-missing-generic-family-keyword error, which you either would have to turn off or add a generic font-family after Font Awesome, which is possibly easier to try for debugging purposes.

@dplacey Just wondering, do you have got the searchPseudoElements also working when using the browsersync development environment? Because that does not seem to work properly yet on my local environment.

Thanks in advance!

Greetings,
Wesley

Hey @wcoppens, I did, yeah, but I think it was a fluke.

Since my last post, I ended up doing a good amount more research on things. Meanwhile yarn build was starting to skip building out my production assets. When this started happening, I came across a thread describing an apparent bug with Bootstrap 4—I can’t find the thread at the moment, but when I do I’ll link it.

Getting frustrated, I just rage quit—I wasn’t very far into building out the theme—and went back and began the theme over again using Foundation as the framework instead of Bootstrap hoping maybe the bug I was reading about was somehow related. I haven’t tried using the pseudo elements again, yet, but all of the other things went a heck of a lot smoother for me this time.

Not necessarily helpful for your predicament… but maybe?

Hey @wcoppens, I just tested this for you on my setup. And it seems like there is an error rendering the FA icons from pseudo-classes in the local environment. What happens is that the icon is displayed properly, but the unicode white square character which is used for representing missing ideographs is still showing. Don’t know if that helps.

The fix is two lines: Missing styles on build:production when using Bootstrap 4 navbar · Issue #2017 · roots/sage · GitHub

But that’s unrelated to this topic :smiley:

I am using the searchPseudoElements addition without issues on the main Roots site, implemented as described in this topic by @marcelo2605

Let’s keep this thread on topic, and maybe split off into a new thread if you need further assistance with it

1 Like