ADAM DJ BRETT

Home / Blog / Easier Font Awesome SVGs in 11ty

Inspired by so many #webdevs on the #indieweb I am continuing to work on posting what I am doing and #buildinpublic. It is a little scary but here we go.

I need to hurry up and convert all my Jekyll sites to 11ty at the same time because I feel like I keep relearning the same lessons. Hopefully, this post will help me remember what to do when moving old Jekyll sites into 11ty and Build Awesome: the hard part is rarely the new tool. The hard part is the history around the old site.

To make the move easier and quicker, I kept the site in liquid. The major issue that I had was that the minimal mistakes Jekyll theme had very old class names and Font Awesome web font implementation.

As I was working on the WOCATI repo, I sstruggled to recall how to fix this based on previous experience. The site started as Jekyll plus Minimal Mistakes. Minimal Mistakes uses Font Awesome in many places, and the old site expected Font Awesome CSS and font files to load in the browser. I wanted the Build Awesome version to use inline SVGs instead. Finally I found the guide I used last time thanks to 11ty Bundle. In the bundle I found equk's guide to the 11ty Font Awesome SVG plugin gave me the path. Following this guide, I used the @11ty/font-awesome plugin to turn <i class="..."> Font Awesome markup into SVG during the Eleventy build. No client-side Font Awesome JavaScript. No full icon font for a page that only needs a few icons.

The basic setup is small:

import fontAwesomePlugin from "@11ty/font-awesome";

export default function (eleventyConfig) {
  eleventyConfig.addPlugin(fontAwesomePlugin, {
    transform: "i[class]",
    shortcode: false,
    defaultAttributes: {
      class: "icon-svg",
      "aria-hidden": "true",
    },
  });
}

That part worked. The real work was making the old theme markup and old theme CSS agree with the new SVG output.

What the plugin changes #

In a traditional Font Awesome setup, a template might include:

<i class="fas fa-fw fa-rss-square" aria-hidden="true"></i>

The browser loads Font Awesome CSS. The CSS maps those classes to a glyph in a web font. The icon appears. The <i> element is a marker that says, "put the right font glyph here."

With @11ty/font-awesome, the build sees that same <i> element and replaces it with SVG. This fits static sites well. The page gets only the SVGs it needs, and the browser does less work.

That mattered for WOCATI because icons were scattered throughout the Minimal Mistakes templates:

<i class="fas fa-fw fa-tags" aria-hidden="true"></i>
<i class="fab fa-fw fa-facebook" aria-hidden="true"></i>
<i class="fas fa-fw fa-rss-square" aria-hidden="true"></i>
<i class="fas fa-search"></i>

I did not need to rewrite those templates into hand-authored SVG. The plugin let the migration keep the old template vocabulary and change the build output.

The first problem: old icon classes #

Here is where [equk's guide](https://equk.co.uk/2025/03/23/11ty-font-awesome-svg-plugin/ came in clutch for me. The guide notes a common problem. Older sites often use old Font Awesome class patterns:

<i class="fa fa-github"></i>

Modern Font Awesome needs the icon family too:

<i class="fab fa-github"></i>
<i class="fas fa-code"></i>

The build plugin needs to know which icon set to use. Is this a brand icon? A solid icon? A regular icon?

WOCATI already had a mix of older and newer class names because Minimal Mistakes had moved in that direction and the site had been in archve mode using a remote theme hence the blending of old and new. Thankfully, fas, fab, far, and fa-fw were already present in most places. But this is still the first thing to check on an older site. If the plugin runs but icons disappear, do not start with SVG debugging. Search templates and Markdown for plain fa classes that do not name a family.

Useful searches:

rg '<i class="fa ' .
rg 'class="[^"]*\bfa-[a-z0-9-]+' _includes content src

The fix is inventory work. It makes the rest of the migration easier.

The second problem: SVGs are not font glyphs #

After using equk's method, the svgs were MASSIVE. This is where the guide helped most and the part I kept forgetting. equk added a default SVG class through defaultAttributes, then styled that class in CSS.

I used the same pattern:

eleventyConfig.addPlugin(fontAwesomePlugin, {
  transform: "i[class]",
  shortcode: false,
  defaultAttributes: {
    class: "icon-svg",
    "aria-hidden": "true",
  },
});

Then in CSS:

.icon-svg {
  display: inline-block;
  width: 1em;
  height: 1em;
  vertical-align: -0.125em;
  overflow: visible;
  fill: currentColor;
}

.icon-svg.fa-fw {
  width: 1.25em;
  text-align: center;
}

.search__toggle .icon-svg {
  display: block;
}

The key idea is not only width: 1em or height: 1em. The SVG needs to behave like the font glyph it replaced. Font icons inherit text color and scale with surrounding text. If the replacement SVG does not do that, every icon becomes a layout problem.

In WOCATI, fill: currentColor made the SVG inherit the text color. 1em kept it sized like text. The .fa-fw rule preserved the fixed-width rhythm expected by the old theme. The search button needed one extra rule because its icon sits inside a button instead of flowing inline with text.

Is 1em too big? #

At one point, I asked my newfound rubber ducky desktop friend this directly: Is 1em too big? (the duck did not answer)

My answer: not as a default. 1em is the right starting point because the SVG replaces a font glyph. If an icon sits next to text, it should usually match the text size.

But 1em is not a rule for every context. It is a baseline and for many of the sites I manage its too large. Smaller icons work better in some places:

  • dense metadata rows
  • tiny footer links
  • compact nav controls
  • buttons where the icon is decorative rather than the main affordance

For those cases, use context-specific CSS instead of changing the global icon size:

.page__meta .icon-svg {
  width: 0.9em;
  height: 0.9em;
}

The global rule should make most icons ordinary. Then each interface context can tune from there.

Why this is better than shipping old Font Awesome CSS #

The old Font Awesome setup is easy to understand, but it has a cost. You ship CSS and font files for a broad icon system even when a page only needs a few icons. The browser also has to resolve the visual result.

The plugin moves that work into the build. In the WOCATI migration, this fit the larger project pattern:

  • preserve the existing template language where possible
  • make the build explicit
  • remove old runtime assumptions
  • keep public URLs and visual behavior stable
  • clean out Jekyll-era cruft after the Build Awesome version works

Font Awesome SVGs are a small example of that larger migration principle. We did not rewrite every footer, author card, and social link. We made the build smarter, then added the CSS needed to make the new output behave like the old UI.

The recipe I would use next time #

this section is for future Adam

For the next 11ty or Build Awesome site, I would handle Font Awesome SVGs this way:

  1. Install the plugin.
npm install @11ty/font-awesome
  1. Add it to the Eleventy config.
import fontAwesomePlugin from "@11ty/font-awesome";

eleventyConfig.addPlugin(fontAwesomePlugin, {
  transform: "i[class]",
  shortcode: false,
  defaultAttributes: {
    class: "icon-svg",
    "aria-hidden": "true",
  },
});
  1. Search for old class names.
rg '<i class="fa ' .
  1. Replace old generic classes with modern icon families.
<i class="fab fa-github"></i>
<i class="fas fa-link"></i>
<i class="far fa-calendar-alt"></i>
  1. Add the baseline SVG CSS.
.icon-svg {
  display: inline-block;
  width: 1em;
  height: 1em;
  vertical-align: -0.125em;
  overflow: visible;
  fill: currentColor;
}

.icon-svg.fa-fw {
  width: 1.25em;
  text-align: center;
}
  1. Fix individual UI contexts only when needed.
.search__toggle .icon-svg {
  display: block;
}
  1. Remove old Font Awesome font imports and font files after checking the build output. Clean your code, keep it all neat and tidy, especially for a site in archival mode. Otherwise, you will later wonder whether an icon comes from a font, an SVG transform, an old theme stylesheet, or a client-side script.

The migration lesson #

This made the WOCATI migration feel less like a full rewrite. The site had old Jekyll templates, Minimal Mistakes conventions, WordPress-era assets, and a lot of history. The Font Awesome piece could have become another reason to rewrite everything. Instead, @11ty/font-awesome lets the site keep familiar markup and get better output.

That is the kind of 11ty migration I like. The tool does not force a dramatic break with the past. It lets you remove the parts that no longer need to be there.

Thanks to equk's post for making the path clear. The implementation was only a few lines of config. The real lesson was knowing where to look when the icons appeared, worked, and still looked wrong.

Tags : 11ty build-awesome font-awesome web-development static-sites wocati

Webmentions

No webmentions yet.

Previous

Review of Leon Niemoczynski's *Speculative Realism: An Epitome*

A review of Leon Niemoczynski's Speculative Realism: An Epitome, tracing realism after Kant, correlationism, and the movement's contested legacy anew.