Search code examples
htmlgetfavicon

Can/should I use parameters in links to favicon, tiles and the like?


These days we can specify boatloads of icons, startup images, tile images etc. specific for different devices in the head section of our websites. Almost every version needs its own meta-tag which specifies its target and resolution, eg.

<link rel="icon" type="image/png"        href="/icons/icon-32.png"  sizes="32x32"  />
<link rel="apple-touch-icon-precomposed" href="/icons/icon-152.png" sizes="152x152"/>
<link rel="apple-touch-icon-precomposed" href="/icons/icon-180.png" sizes="180x180"/>
<meta name="msapplication-TileImage"  content="/icons/tile-270x270.png"/>

That's a little bit of boilerplate, but templates can deal with that. But let's assume I use a webserver that's a tiny bit more complicated and actually needs code for all these routes. Maybe I want to do something with the images dynamically like generate icon resolutions lazily the first time they are requested or count how often they are requested or anything a bit fancy like that. The simplest way to do that would be to have a single handler that just gets the details via get-parameters. So the links would now look like this:

<link rel="icon" type="image/png"        href="/icon.png?h=32&w=32"   sizes="32x32"  />
<link rel="apple-touch-icon-precomposed" href="/icon.png?h=152&w=152" sizes="152x152"/>
<link rel="apple-touch-icon-precomposed" href="/icon.png?h=180&w=180" sizes="180x180"/>
<meta name="msapplication-TileImage"  content="/icon.png?h=270&w=270&s=tile"/>

From a backend-programmer point of view, this solution looks quite elegant. But is it actually a good idea to expose the implementation detail in this way without rewrite rules?

From all I've read it seems the url resolution code in major browsers handles meta tags the same as it handles all other links, so the extra parameters shouldn't be a problem there. But maybe I overlooked one with a different philosophy?

And what about caching? Theoretically, the parameters don't change, so the icons should still be cacheable - but I could understand why a browser would choose not to. On the other hand, maybe icon caching has different rules anyway because it's so important?

Of course I can just try it, but if you have any experience with such an approach it could keep me from blindly walking down the wrong track.


Solution

  • TL;DR Your solution will work, yet it has some drawbacks. You probably shouldn't do this.

    What you plan to do (ie. icon.png?h=32&w=32 and friends) should work. Browsers support such paths for icons. Actually, adding a suffix (eg. icon.png?v=2) is a documented technique to force browsers to reload icons, for example when they are updated in the course of a site revamping. I have no definitive answer regarding caching. Although it is well-known that browsers tend to not refresh icons (this is a classic source of hassle for web developers playing with icons before picking the final version), that doesn't mean browsers really play nicely with icons and cache.

    This said, I see several drawbacks to this technique:

    • Because you specify the icon dimensions as parameters, I understand that you plan to apply a single, one-size-fits-all transformation to generate the various icons. I suppose you have a high resolution image somewhere and you simply scale it down when a client is asking for, say, a 32x32 version that you didn't generate yet. This is probably not a good idea. Different platforms need different icon designs. While iOS virtually prevents transparent icons (it applies a black background, which is almost never what you want), Android favors transparency (look at the Google native apps icons). You should better create your icons platform-per-platform.
    • You mention the ability to count how often the icons are accessed. If you come to this, I advice you to rely on a trusty analytics tool which will do this the right way, with graphics and all. Don't code yourself a half-backed solution yourself when someone else did the hard work for you.
    • Name conventions matter. Whatever you declare in the HTML, iOS Safari tries to access some icons such as /apple-touch-icon.png. /favicon.ico is another classic. Don't get me wrong: if you delare everything (as you plan to do), everything will work. You will only notice 404 in your logs. Nothing harmful.

    If you don't want to simply get some HTML code and corresponding images and throw them right in your project, I advice you to use a tool such as Gulp or Grunt to generate these assets at "compile time" so your project is not a mess.