Photo by Reza Rostampisheh on Unsplash
Favicons are low-resolution website icons that web browsers use to help identify bookmarks, tabs, and desktop icons at a glance - and they're easy to add in Metalsmith.
Project setup
To keep this article short and to the point we're not going to set up a full website, just enough to show sample usage. See "Starting a Metalsmith Project" for a more complete article on how to set up a Metalsmith project.

Starting a Metalsmith Project
Sep 19, 2019 · 12 min read
Metalsmith is a plugin-based static site generator originally from Segment. It's a current favorite of mine because of how sites are built as a pipeline of plugins where the output of each plugin is the input of the next. This allows for strong control over what happens and when it happens.
Installing packages
Starting with an empty project, install some Metalsmith packages:
npm install --save metalsmith metalsmith-favicons metalsmith-layouts jstransformer-handlebarsmetalsmithfor the base project.metalsmith-faviconsto generate icon files.metalsmith-layoutsandjstransformer-handlebarsto render Handlebars templates
Source file structure
Create the following directories and files for use in the build pipeline:
.
├── index.js
├── layouts
│ └── page.hbs
└── src
├── favicon.png
└── index.htmlAny valid PNG file will do for src/favicon.png, so use a logo of yours or another website's.
Then fill in your src/page.hbs like this:
<!DOCTYPE html>
<html>
<head>
{{#each favicons.html}}
{{{ this }}}
{{/each}}
</head>
<body>
{{{ contents }}}
</body>
</html>Which will serve as a base template for us to be able to use the favicons metadata.
You can fill src/index.html in with any content such as lorem ipsum, it isn't important for the point of this article.
Writing the source files
Set up your index.js file like this:
const Metalsmith = require('metalsmith');
const favicons = require('metalsmith-favicons');
const layouts = require('metalsmith-layouts');
// Define some site-wide metadata
const siteName = 'Your Webiste Name';
const siteDescription = 'Your website description.';
const siteURL = 'https://your.website.com';
Metalsmith(__dirname)
.source('./src') // source directory for the pipeline
.use(favicons({ // generate icon files
src: 'favicon.png',
dest: '.',
appName: siteName,
appDescription: siteDescription,
developerName: siteName,
developerURL: siteURL,
start_url: siteURL,
icons: {
android: true,
appleIcon: true,
favicons: true,
windows: true
}
}))
.use(layouts({ // use Handlebars templating
pattern: '**/*.html',
default: 'page.hbs',
engine: 'handlebars'
}))
.destination('./build') // destination directory of the pipeline
.clean(true) // clean the destination directory before build
.build(function (err) { // execute the build
if (err) {
throw err;
}
});This will:
- Generate a
build/manifest.jsonweb app manifest . - Generate
build/android-chrome-*.pngicons to be used inbuild/manifest.json. - Generate
build/apple-touch*.pngicons to be used in<link rel="apple-touch-icon">s. - Generate
build/favicon.*icons to be used in<link rel="icon">s. - Generate a
build/browserconfig.xmlbrowser configuration schema reference . - Generate
build/mstile-*.pngicons to be used inbuild/browserconfig.xml. - Process
src/index.htmlthroughlayouts/page.hbs, adding the icon metadata to the page.
Note this does a lot more than just generate a single favicon.ico or favicon.png, it also generates a number of non-image files used for defining "web apps" or "pinned sites." See the RealFaviconGenerator FAQ for a great explanation of each of the files generated.
Build
Run the build command like normal:
node indexThen open the resulting build/index.html in your browser, and you should the favicon displayed.

