How to Fix Flashing FontAwesome Icons on Page Load

If you ever used FontAwesome with a server side rendered framework like nextjs, remix or static site generator like GatsbyJS, you probably noticed it. On each page load, the FontAwesome icons are huge for a split second. After some research, I found out why that happens and how to fix it:

FontAwesome icons flicker on page load because their CSS is loaded only after they are displayed. Even though scaling them via inline CSS makes the flashing less noticeable, including the FontAwesome styles via an import into the root route effectively eliminates the flashing.

Let's look at how to apply those two methods to your problem:

Scaling FontAwesome Icons Inline

If the problem is rather local and not in your whole app / website, maybe this fix will be more feasible:

<FontAwesomeIcon icon={faEnvelope} width="16" />

By giving the element a width inline, even without external CSS, the icon is not rendered hugely. Instead, you may notice a small change in size on page load, depending on what the icon's actual size is.

If you use icons only e.g. in the menu, you can consider playing with the width until the desired width is reached and the icon is not changing in size after the stylesheet is loaded. Take care of the fact that on different screen sizes different icon sizes might be needed.

If you display icons at several places within your site, consider trying the next solution that eliminates the flashing completely:

Loading FontAwesome Stylesheet in Root Route

Apart inlining a specific size, you can import the FontAwesome stylesheet to be bundled within the rest of your deliverable code.

This works a bit different depending on what framework you are using, but you need to find a place where if you put code, it will be executed / sent for each site.

For vanilla react, this might be inside index.html or index.js while in remix, it's root.tsx and for next it's the pages/_app.js layout. This is what you want to do:

import '@fortawesome/fontawesome-svg-core/styles.css';
import { config } from "@fortawesome/fontawesome-svg-core";
// Prevent fontawesome from dynamically adding its css since we are going to include it manually
config.autoAddCss = false;

This will make FontAwesome not add their CSS automatically. Instead, we got the  faStyleSheetUrl and will use it manually now. Again, depending on what framework you are using, you have to add the stylesheet differently. Next.js or React will automatically import the CSS and apply it without the client needing to wait for an external stylesheet.

If you are using a framework that doesn't automatically add / apply imported CSS, you have to do it manually. Here is an example on how to accomplish that in remix.

import faStylesheetUrl from'@fortawesome/fontawesome-svg-core/styles.css';
import { config } from "@fortawesome/fontawesome-svg-core";
// Prevent fontawesome from dynamically adding its css since we did it manually above
config.autoAddCss = false;

export const links: LinksFunction = () => {
  return [{ rel: "stylesheet", href: tailwindStylesheetUrl },
    { rel: "stylesheet", href: customStylesheetUrl },
    { rel: "stylesheet", href: faStylesheetUrl }
  ];
};

If you are using another framework, you should try to import the contents of the stylesheet and put it into the header (like shown for remix above).

This will make the CSS for styling the icons available in the same file where the icons are rendered, which means no flickering.