Go to content
.

Creating the various sizes of Apple Touch Icons is one of the more tedious tasks in web development. iOS uses the Apple Touch Icon when a user adds the website to their home screen and since most websites now include them, many things use Apple Touch Icons when they need to display a higher quality version of the Favicon. According to Apple's Human Interface Guidelines on App Icons we need to add icons in the following sizes to our websites: 180x180, 167x167, 152x152, and 120x120.

While sometimes it is necessary to optimise our icon for each size, in many cases a simple resize is good enough. Instead of having to manually create all four versions of the app icon, we can use JavaScript templates in Eleventy to automatically generate a version for each size.

We will use the sharp library to resize the file and will start by installing it as a dependency:

npm install --save-dev sharp

Next we create a JavaScript template in the input directory of our Eleventy site that reads the original image file, resizes the image for each variant and saves them into the output directory. In my case the input directory is site/ and the output directory is dist/:

const sharp = require('sharp');
const promisify = require('util').promisify;
const fs = require('fs');

const readFile = promisify(fs.readFile);

class AppleTouchIcon {
  async readOriginalIcon() {
    return await readFile('./site/images/apple-touch-icon.png');
  }

  async resizeIcon(icon, size) {
    return await sharp(icon)
      .resize(size, size)
      .toFile(`./dist/images/apple-touch-icon-${size}x${size}.png`);
  }

  async render() {
    // See https://developer.apple.com/design/human-interface-guidelines/ios/icons-and-images/app-icon/
    const iconSizes = [120, 152, 167, 180];
    const originalIcon = await this.readOriginalIcon();
    await Promise.all(
      iconSizes.map(async (size) => {
        this.resizeIcon(originalIcon, size);
      })
    );

    return undefined;
  }
}

module.exports = AppleTouchIcon;

Since the render method of the JavaScript template always returns undefined Eleventy will not create an additional file.

The last step is to include the Apple Touch Icons in the <head> of our page, in most cases you will have a layout which is used for all pages:

<link rel="apple-touch-icon" sizes="180x180" href="/images/apple-touch-icon-180x180.png">
<link rel="apple-touch-icon" sizes="167x167" href="/images/apple-touch-icon-167x167.png">
<link rel="apple-touch-icon" sizes="152x152" href="/images/apple-touch-icon-152x152.png">
<link rel="apple-touch-icon" sizes="120x120" href="/images/apple-touch-icon-120x120.png">