Favicon Gremlins in Static Web Apps + Webpack
Favicons, or as I like to call them, image gremlins from hell, can be mildly frustrating to add to your application. I successfully conquered the little beasts, so I figured I owed it to the community to share how I vanquished them.
The back story
Step 1: Cheat
Don’t attempt to generate your own favicons. This is not the 1990’s when you could get away with just one favicon.ico file. You need like 4236* now.
*I’m lying (it’s more like 27 at the time of writing), but they do seem to grow at an exponential rate. Just like gremlins. So don’t add water.
Create the image you want to use as the basis for all your favicons. For the best results, it should be at least 260x260.
Next, sail over to RealFaviconGenerator and select your base favicon image.
This is the best part… they generate all 4236* files that you need to serve up favicons for all browsers and platforms! Plus they give you the 324** lines of code you need to add to the head of your HTML!
** Again, I might be exaggerating (it’s more like 16 at the time of writing).
Download the zip file containing all your images.
Copy those lines of code into the head of every html file in your project (the joys of using no front-end framework never cease).
A note on my current Webpack set up
Before we dig into how to handle the favicons, let me give you a flavor of my current Webpack set up so that you can determine which of my steps are relevant to your application.
html-loader for loading, extracting, resolving URLs (e.g., for
<img> sources), and building my HTML files:
Step 2: Add the favicons
Unzip the file you downloaded from RealFaviconGenerator, and copy or move the contents to a separate folder in your app or src directory. In my app, it is called app/favicons/. We create a separate directory because we want a super easy way to pass all these files to the root of our build folder for optimal treatment by all browsers.
Now is when you’re probably wondering, “Do I need to write a
require statement for all 4236* files?!?!?!”. No. Please use the powers of software engineering to help you. Create a helper file that programmatically loads all files in the app/favicons/ directory for you (of course, change the path according to your application set up):
Finally, add it to your each of your entry point files, like so:
Step 3: Adjust Webpack config
Finally, we need to tell Webpack what to do and what not to do with these files:
- Simply copy all the files to the root of the build folder using
- Don’t do any extra image processing that we may do on other images, or
excludethem from other rules
Here is my sample set up:
But why… ?
Why didn’t I use my image loader for my favicons with hashes to make cache invalidation easier? Because unfortunately, I haven’t figured out a way for Webpack to resolve the
href attribute for a
<link> yet. If you know how, please let me know!
Why didn’t I use
favicons-webpack-plugin? It wouldn’t automatically update my HTML in this setup. I also didn’t want to add a bunch of extra dependencies slowing down my dev builds when this method was just as easy.
I’d love to hear how you vanquish your own gremlins or if you find an improvement on this method for static apps — please share in the comments!
If you liked this story, give it a 👏 to share the love.