5

I looked through my website access log files and I saw lots of requests for icon files (with counts):

49146 /apple-touch-icon-precomposed.png
45836 /apple-touch-icon.png
40287 /favicon.ico
 6752 /apple-touch-icon-120x120-precomposed.png
 6669 /apple-touch-icon-120x120.png
  886 /apple-touch-icon-152x152-precomposed.png
  876 /apple-touch-icon-152x152.png
  318 /apple-touch-icon-76x76-precomposed.png
  317 /apple-touch-icon-76x76.png
   71 /apple-touch-icon-57x57-precomposed.png
   70 /apple-touch-icon-57x57.png
   46 /apple-touch-icon-114x114-precomposed.png
   44 /apple-touch-icon-114x114.png
   30 /apple-touch-icon-72x72-precomposed.png
   30 /apple-touch-icon-72x72.png

How should I create icon files to satisfy all these requests? What file formats, and image sizes should I create? What meta tags should I include in my pages for site icons?

I'd like my site's icon to show up:

  • In the browser's URL bar
  • When a user bookmarks my site
  • When my site is added to the mobile home screen on iPhone or Android
  • When my site is shared on Facebook and other social media sites
0

2 Answers 2

8
  • Your icon should be square. It needs to be resized in a variety of ways to support every browser and application that will use it.
  • It is fine to use PNG files, but you should create an ICO file with multiple sizes in it. This cuts down on the number of meta tags you have to use.
  • You can name your files however you like. It is fine to use the default names (favicon.ico, apple-touch-icon.png, etc) or use your own names and redirect the default names.
  • The "precomposed" icons that Apple devices request are used as is, whereas the non-precomposed ones get rounded corners and drop shadows added to them. If you don't want your icon modified in this way, it is best to provide them procomposed.
  • For social sites, you need a much larger icon. 1200x1200 is the optimal size that works well with both Facebook and Reddit.
  • Internet Explorer and Edge now fetch browserconfig.xml to find the icons used when somebody adds your site to the Windows desktop. There are specific sizes that need to be included.
  • Chrome on Android uses manifest.json to learn about the icons available when somebody puts a bookmark on the home screen. The manifest also contains a name for the bookmark.
  • It would be nice to be able to specify a scalable vector graphic for your icons, but most browsers don't support SVG favicons. Only Firefox does right now.

I end up creating the following files:

  • SITENAME.ico
  • SITENAME-16x16.png
  • SITENAME-32x32.png
  • SITENAME-48x48.png
  • SITENAME-57x57.png
  • SITENAME-72x72.png
  • SITENAME-76x76.png
  • SITENAME-114x114.png
  • SITENAME-120x120.png
  • SITENAME-128x128.png
  • SITENAME-144x144.png
  • SITENAME-152x152.png
  • SITENAME-270x270.png
  • SITENAME-558x270.png
  • SITENAME-558x558.png
  • SITENAME-1200x630.png
  • SITENAME-1200x1200.png
  • browserconfig.xml
  • manifest.json

I put the following code into my .htaccess file to redirect requests for the default file name:

# Redirect favicon requests
Redirect permanent /favicon.ico /SITENAME.ico

# Redirect apple touch icon requests for specific sizes that we have
Redirect permanent /apple-touch-icon-152x152.png /SITENAME-152x152.png
Redirect permanent /apple-touch-icon-152x152-precomposed.png /SITENAME-152x152.png
Redirect permanent /apple-touch-icon-120x120.png /SITENAME-120x120.png
Redirect permanent /apple-touch-icon-120x120-precomposed.png /SITENAME-120x120.png
Redirect permanent /apple-touch-icon-114x114.png /SITENAME-114x114.png
Redirect permanent /apple-touch-icon-114x114-precomposed.png /SITENAME-114x114.png
Redirect permanent /apple-touch-icon-76x76.png /SITENAME-76x76.png
Redirect permanent /apple-touch-icon-76x76-precomposed.png /SITENAME-76x76.png
Redirect permanent /apple-touch-icon-72x72.png /SITENAME-72x72.png
Redirect permanent /apple-touch-icon-72x72-precomposed.png /SITENAME-72x72.png
Redirect permanent /apple-touch-icon-57x57.png /SITENAME-57x57.png
Redirect permanent /apple-touch-icon-57x57-precomposed.png /SITENAME-57x57.png

# Redirect all other apple touch icon requests to the default size
RedirectMatch permanent "(?i)/apple-touch-icon.*\.png$" /SITENAME-152.png

I use the following meta tags in the <head> section of my pages. Note that the URL in the tag for Facebook has to be absolute or Facebook doesn't accept it. Your icon is fine for Facebook only on your home page. You probably want more specific images to show up on Facebook when users share individual articles.

<link rel=icon type="image/x-icon" sizes="16x16 32x32 48x48 72x72 152x152" href="/SITENAME.ico">
<link rel=apple-touch-icon-precomposed href="/SITENAME-152x152.png">
<meta name=msapplication-config content="/browserconfig.xml">
<meta property="og:image" content="http://SITENAME.TLD/SITENAME-1200x1200.png">
<meta property="og:type" content=website>
<link rel=manifest href="/manifest.json">

The contents of browserconfig.xml should be:

<?xml version="1.0" encoding="utf-8"?>
<browserconfig>
    <msapplication>
        <tile>
            <square70x70logo src="/SITENAME-70x70.png"/>
            <square150x150logo src="/SITENAME-150x150.png"/>
            <square310x310logo src="/SITENAME-310x310.png"/>
            <wide310x150logo src="/SITENAME-310x150.png"/>
        </tile>
    </msapplication>
</browserconfig>

The contents of manifest.json should be:

{
    "name":"SITENAME",
    "icons":[
        {"src":"/SITENAME-48x48.png","sizes":"48x48","type":"image/png"},
        {"src":"/SITENAME-144x144.png","sizes":"144x144","type":"image/png"},
        {"src":"/SITENAME-192x192.png","sizes":"192x192","type":"image/png"}
    ],
    "start_url":"/",
    "display":"standalone",
    "orientation":"portrait"
}

To automate the image resizing, I created a script. It expects an SVG format icon that is square and larger than 1200x1200. It uses Inkscape, ImageMagick, and Pngcrush to create and optimize the appropriate files.

#!/bin/sh

set -e;

img="$1"
outdir=target/img

if [[ $img != *.svg ]]
then
    echo "No SVG image specified"
    exit 1
fi

if [ ! -f "$img" ]
then
    echo "Image file does not exist: $img"
    exit 1
fi

basename=$(basename "$img");
basename="${basename%%.*}"

mkdir -p "$outdir"

# http://stackoverflow.com/questions/9853325/how-to-convert-a-svg-to-a-png-with-image-magick
png="$outdir/$basename.png"
if [ ! "$png" -nt "$img" ]
then
    inkscape -z -e "$png" -d 72 "$img"
fi

for size in 16x16 32x32 48x48 57x57 70x70 72x72 76x76 114x114 120x120 144x144 150x150 152x152 310x150 310x310 1200x630 1200x1200
do
    out="$outdir/$basename-$size.png"
    if [ ! "$out" -nt "$img" ]
    then
        TMP=`mktemp --suffix=.png`
        convert "$png" -resize "$size^" -gravity center -crop "$size+0+0" "$TMP"
        pngcrush -brute $TMP $out
        rm $TMP
    fi
done

out="$outdir/$basename.ico"
if [ ! "$out" -nt "$img" ]
then
    convert "$outdir/$basename-16x16.png" "$outdir/$basename-32x32.png" "$outdir/$basename-48x48.png" "$outdir/$basename-72x72.png" "$outdir/$basename-152x152.png" "$out"
fi

Sources:

2
  • This is great work building the script and posting it here, but I've always used RealFaviconGenerator.net which is free (though I’ve donated several times because it's so useful) and which is more comprehensive. It also handles Android & Windows launchers and tiles, plus Safari's 'pinned tabs', and probably more stuff yet to be discovered. Oh, and put a rule disabling logging for the favicons directory, you don't need all those requests cluttering up the logs. Commented Mar 15, 2016 at 20:29
  • I like RealFaviconGenerator.net. It has really nice compression options. It doesn't deal with the version for sharing on Facebook though. Commented Mar 15, 2016 at 22:48
1

Why not generate most icons on the fly?

In PHP (and probably other server-side scripting languages), there are functions you can use to generate an image and display it on the screen based on size.

Also, use a script that rewrites URLs on the server software. Here's how you can do it with apache and PHP.

In the apache config file, add these lines:

RewriteRule ^apple-touch-icon-([0-9]+)x([0-9]+)(-precomposed|).png/?$ /apple.php?W=$1&H=$2 [NC,L]
RewriteRule ^apple-touch-icon(-precomposed|).png/?$ /apple.php?W=57&H=57 [NC,L]

Then create a php script named apple.php in document root with these contents:

    <?php
      $icon="/path/to/websiteiconinpng.png";
      $i=imagecreatefrompng($icon);
      $w=intval($_GET['W']);if ($w < 57 || $w > 150){$w=57;}
      $h=intval($_GET['H']);if ($h < 57 || $h > 150){$h=57;}
      $i2=imagecreate($w,$h);
      imagecopyresampled($i2,$i,0,0,0,0,$w,$h,imagesx($i),imagesy($i));
      imagedestroy($i);
      ob_start();
      imagepng($i2,NULL,9);
      $data=ob_get_contents();
      ob_end_clean();
      imagedestroy($i2);
      header('Content-type: image/png',true);
      header('Content-length: '.strlen($data),true);
      flush();
      echo $data;
?>

This will then resize the icon and display it based on the user requested size. I added upper and lower size boundaries so that the icon doesn't look funny.

As for favicon.ico, you might as well keep that one as a separate file.

2
  • 3
    Why not generate most icons on the fly? Because this will require more work from the server than serving the files. This can be avoided by caching the generated images.
    – A.L
    Commented Mar 15, 2016 at 19:17
  • 1
    A.L. Caching is a good idea. I was just giving the OP an idea on how he can solve his issue on serving a host of icon files with a bunch of different dimensions in the filename. There could be more dimensions in the future and my script will likely handle those as well. Commented Mar 16, 2016 at 2:57

Not the answer you're looking for? Browse other questions tagged or ask your own question.