Recently I switched from Gatsby to 11ty. There is a Gatsby plugin to generate favicons automatically. I wanted to have something similar for my new blog.
I realized that I don’t want to generate favicons on every build. It does not make sense. I have had the same favicon for 3 years or more.
I found an excellent package called… favicons. It can generate favicons for all platforms, manifest files and even the HTML meta tags.
Initially, I thought to create an 11ty plugin to be rich and famous, but I chose not to. Why? It’s too simple and I don’t see a point to have it as a plugin.
Let’s generate favicons.
npm install favicons --save
The script requires three variables:
- a path to an image from which we want to generate favicons
- a path to a directory where we want to store all files
- a path to a directory where we want to save the HTML meta tags
The script is straightforward. I keep it inside _scripts
directory.
const fs = require("fs");const favicons = require("favicons");
const source = "content/images/eshlox.jpg";const faviconsPath = "_assets/favicons/";const faviconsHtmlPath = "_layouts/_favicons.njk";
const configuration = { path: "/assets/favicons", appName: "eshlox.net", appShortName: null, appDescription: null, developerName: "eshlox", developerURL: "https://eshlox.net", dir: "auto", lang: "en-US", background: "#fafafa", theme_color: "#111111", appleStatusBarStyle: "black-translucent", display: "standalone", orientation: "any", scope: "/", start_url: "/", version: "1.0", logging: false, pixel_art: false, loadManifestWithCredentials: false, icons: { android: true, appleIcon: false, appleStartup: false, coast: false, favicons: true, firefox: false, windows: false, yandex: true, },};
const callback = function (error, response) { if (error) { console.log(error.message); return; }
if (!fs.existsSync(faviconsPath)) { fs.mkdirSync(faviconsPath); }
response.images.forEach((element) => { fs.writeFileSync(`${faviconsPath}/${element.name}`, element.contents); });
response.files.forEach((element) => { fs.writeFileSync(`${faviconsPath}/${element.name}`, element.contents); });
fs.writeFileSync(faviconsHtmlPath, response.html.join("\n"));};
favicons(source, configuration, callback);
You can find the full documentation on Github so update the configuration to your needs. The script uses the favicons
library, which does all the work and then creates a directory, saves all the images, all the files and the HTML in the given paths.
Every time I want to generate or update favicons, I have to run a single command and commit all the files to the repository.
node _scripts/generate_favicons.js
The _assets/favicons
directory content:
tree _assets/favicons
_assets/favicons├── android-chrome-144x144.png├── android-chrome-192x192.png├── android-chrome-256x256.png├── android-chrome-36x36.png├── android-chrome-384x384.png├── android-chrome-48x48.png├── android-chrome-512x512.png├── android-chrome-72x72.png├── android-chrome-96x96.png├── favicon-16x16.png├── favicon-32x32.png├── favicon-48x48.png├── favicon.ico├── manifest.json├── yandex-browser-50x50.png└── yandex-browser-manifest.json
0 directories, 16 files
The _layouts/_favicons.njk
file content:
<link rel="shortcut icon" href="/assets/favicons/favicon.ico" /><link rel="icon" type="image/png" sizes="16x16" href="/assets/favicons/favicon-16x16.png"/><link rel="icon" type="image/png" sizes="32x32" href="/assets/favicons/favicon-32x32.png"/><link rel="icon" type="image/png" sizes="48x48" href="/assets/favicons/favicon-48x48.png"/><link rel="manifest" href="/assets/favicons/manifest.json" /><meta name="mobile-web-app-capable" content="yes" /><meta name="theme-color" content="#111111" /><meta name="application-name" content="eshlox.net" /><link rel="yandex-tableau-widget" href="/assets/favicons/yandex-browser-manifest.json"/>
That’s all I need. I can easily include the _layouts/_favicons.njk
file in my _layouts/base.njk
to add favicons to all pages.
{% include "./_favicons.njk" %}
You can see the result on this blog.