- 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: