HTML / CSS - How to preload fonts using the link tag and rel="preload" attribute - 2022

In a series of recent posts I have optimised my site as Google lighthouse / Pagespeed has shown some performance issues. This post is on how to preload fonts, which is simple, yet if you get an attribute wrong it does not work. Here is a working example for my website, which is just a simple link element preloading a font from Google:

<link rel="preload" as="font" type="font/woff2" 
      href="/assets/fonts/font-awesome/fontawesome-webfont.woff2?v=4.5.0" 
      crossorigin="anonymous">

In the above we create a link element with the rel="preload" attribute which is the basis of preloading anything. We give it the type “font/woff2” (font type) and point it to where the asset is using the href attribute. Without the crossorigin or crossorigin="anonymous" attribute the font is not loaded, as your browser fetches the font using anonymous CORS and therefore this attribute is needed. Without it, it will not be a CORS request.

You can leave your CSS unchanged as long as the href in the preload tag matches the one in the CSS. Even though you do not have to change anything, I will leave my @font-face CSS for FontAwesome as a reference:

@font-face {
    font-family: 'FontAwesome';
    font-display: swap;
    src: url("../fonts/font-awesome/fontawesome-webfont.eot?v=4.5.0");
    src: url("../fonts/font-awesome/fontawesome-webfont.eot?#iefix&v=4.5.0") format("embedded-opentype"),url("../fonts/font-awesome/fontawesome-webfont.woff2?v=4.5.0") format("woff2"),url("../fonts/font-awesome/fontawesome-webfont.woff?v=4.5.0") format("woff"),url("../fonts/font-awesome/fontawesome-webfont.ttf?v=4.5.0") format("truetype"),url("../fonts/font-awesome/fontawesome-webfont.svg?v=4.5.0#fontawesomeregular") format("svg");
    font-weight: normal;
    font-style: normal
}

If the above is not working, make 100% sure that the urls match between the HTML and CSS. I had an issue with an extra query parameter that I spent some time on. Make sure you have nothing extra in the URL between your CSS and HTML!

That is all there is to it, let me know in the comments down below if you made this work or had other issues! :)