I just figured out how to use Font Awesome 6 in a Rails 7 project that uses importmaps. I’m not entirely sure why this works and why some of the workarounds are needed, but my googling yielded no results when I was searching so hopefully here I’ll be saving the next person some time.

If you search Rubygems for gems with the name “font awesome” you’ll find quite a few but I didn’t like any of them. They all use the font version of the icons, instead of the SVG, or they are very outdated, or they expect you to use SCSS, which I’m not using at the moment. But ultimately, the team at Font Awesome maintains the NPM packages and we should use those directly, not re-wrap packages that will always be out of date.

For me, using NPM packages directly was higher priority than using importmaps. That’s how strongly I feel about it. I would have installed Webpacker to use Font Awesome’s main package.

I managed to make this work, but if I’m frank, I’m not 100% sure why the workarounds are needed, so if you have any insights about it or how to improve this, please drop a comment.

Font Awesome’s documentation says you should install the fontawesome-free package:

npm install --save @fortawesome/fontawesome-free

Instead we are going to pin that package, but also some of the dependencies we need later:

./bin/importmap pin @fortawesome/fontawesome-free \
                    @fortawesome/fontawesome-svg-core \
                    @fortawesome/free-brands-svg-icons \
                    @fortawesome/free-regular-svg-icons \
                    @fortawesome/free-solid-svg-icons

This adds the following lines to your importmap.rb:

pin "@fortawesome/fontawesome-free", to: "https://ga.jspm.io/npm:@fortawesome/fontawesome-free@6.0.0/js/fontawesome.js"
pin "@fortawesome/fontawesome-svg-core", to: "https://ga.jspm.io/npm:@fortawesome/fontawesome-svg-core@1.3.0/index.es.js"
pin "@fortawesome/free-brands-svg-icons", to: "https://ga.jspm.io/npm:@fortawesome/free-brands-svg-icons@6.0.0/index.es.js"
pin "@fortawesome/free-regular-svg-icons", to: "https://ga.jspm.io/npm:@fortawesome/free-regular-svg-icons@6.0.0/index.es.js"
pin "@fortawesome/free-solid-svg-icons", to: "https://ga.jspm.io/npm:@fortawesome/free-solid-svg-icons@6.0.0/index.es.js"

Then Font Awesome’s documentation says you should add these lines to your code:

<script defer src="/your-path-to-fontawesome/js/brands.js"></script>
<script defer src="/your-path-to-fontawesome/js/solid.js"></script>
<script defer src="/your-path-to-fontawesome/js/fontawesome.js"></script>

Which might make you think this is a good idea:

<script defer src="https://ga.jspm.io/npm:@fortawesome/fontawesome-free@6.0.0/js/brands.js"></script>
<script defer src="https://ga.jspm.io/npm:@fortawesome/fontawesome-free@6.0.0/js/solid.js"></script>
<script defer src="https://ga.jspm.io/npm:@fortawesome/fontawesome-free@6.0.0/js/fontawesome.js"></script>

But it doesn’t work. It fails with this error:

Here I’m a bit confused. How come it fails with that error? Any ideas?

What did work was editing app/javascript/application.js and adding::

import {far} from "@fortawesome/free-regular-svg-icons"
import {fas} from "@fortawesome/free-solid-svg-icons"
import {fab} from "@fortawesome/free-brands-svg-icons"
import {library} from "@fortawesome/fontawesome-svg-core"
import "@fortawesome/fontawesome-free"
library.add(far, fas, fab)

I can’t help but feel that there’s a function or method in fontawesome-free that I could call that would do all the setup automatically with less imports and less library building, but I couldn’t find it yet.