How to use different favicons for development, staging, and production

It’s useful to have different favicons for each environment during development, as Pamela recently pointed out. Here’s how I do it.

First, generate the images. Most graphics editor have some kind of Colorize tool and if you do it often, use ImageMagick to change colors programmatically. If you’re lucky enough to have a green brand logo, a cool combo would be traffic lights. Justsaying.

Now, set the favicons according to your environment. Should you just use /favicon.ico location or point to the location in head? The answer is both. /favicon.ico is useful for third-party plugins whose HTML you don’t control, as well as quick hack pages you can’t be bothered configuring with proper metadata. A link tag in html head is useful for revving the icon when it changes, to bust any cached version. So use both.

To set favicon in HEAD, ensure the path is dynamically generated instead of hard-coded:

  1. %link(rel="icon" href="#{favicon_path}" type="image/x-icon")

The path is generated like such as:

  1. def env_suffix
  2.   Rails.env.production? ? '' : "-#{Rails.env}"
  3. end
  4.  
  5. def favicon_path
  6.   asset_path "favicon#{env_suffix}.ico"
  7. end

It’s arguably bad form to use “production” strings in production, so the env_suffix nonsense above will hide it. If you don’t care about that, just call your production icon favicon-production.ico and save yourself a little hassle.

As mentioned earlier, we also want just /favicon.ico to exist. A quick way to do that is copy it when the apps starts or define /favicon.ico as a route and serve the file as favicon_path, defined above, with sufficient cache expiry time (e.g. 1 day). e.g.:

  1. def favicon
  2. path = ActionController::Base.helpers.asset_path "favicon#{env_suffix}.ico"
  3. send_file path, type:"image/x-icon", disposition:"inline"
  4. end

For bonus points, you might want to use similar techniques to provide overriding stylesheets for development and staging. Then you can introduce a text label or change background color, etc.

Announcing Faviconist

faviconist screenshot

I have made a new Favicon generator, Faviconist. Since most favicons are just a letter with some colour theme, I found it crazy to have to open up a photo editor every time I wanted a new favicon. Or alternatively, it’s easy enough to convert an image with ImageMagick, but most images don’t scale down nicely to a tiny icon! So the aim here is not an editor as such, but a true “favicon generator”.

Using Faviconist

To create a favicon, it’s as simple as typing the first letter of your website. But you probably don’t want the default colour scheme, so it’s easy enough to tweak. Under the covers, Favicon has a concept of a “FillStyle” and both foreground and background are instances of FillStyle, so they have the same flexibility. You can have a solid fill style (just a single colour), a linear gradient, or a radial gradient.

For simplicity, Linear gradients don’t have stops (it’s just a linearly increasing spectrum from start to finish), though you can choose the direction. And in the same sprit of simplicity, radial gradients may only begin at some points, and their span is fixed. The guiding principle here is “YAGNI” – You Ain’t Gonna Need It. I’m catering for the 95% of people who don’t want to micro-design their icons; the rest will still need to resort to PhotoShop et al.

The preview images are PNGs, which can easily be downloaded directly. However, another gripe of mine is the whole thing of downloading to hard drive and uploading back to a server somewhere else. Hot-linking, aka “bandwidth theft”, is rightly a problem for the original image host…but it’s a shame the only way we can deal with it is to silo everything. (A parallel vision of the web, which might have almost succeeded and still might, saw it more as embedded content than a collection of copies and links.) In this case, it’s only favicons, so I’ll just say hot-link and be merry. When you click “Save Favicon”, it saves the icons on my server and you can just cut-and-paste into your own project.

I hope this is useful for quick hacks and hackathons, where favicons are often forgotten! These days Favicons are more useful than here. Of many reasons to use a favicon, things one might forget are: they’re used on third party sites like Google Plus, tabbed browsing is super-popular these days; if you don’t provide favicons, you’ll get 404s in your log files.

And here’s a little tip for you – don’t just use letters. Try special characters, and don’t just limit yourself to ASCII. You have the entirety of Unicode at your disposal!

How Favicon Works

Buzzword Bingo time. There are a number of technologies at work here:

  • HTML5 Canvas In the past, a site like this would have to be powered by the server – every change would require a long wait for the server to generate a new image. But now, we can do it in real-time, in the browser, using Canvas. The only server interaction is conversion to “.ico”; unfortunately, Canvas will output to PNG, but not ICO. And while a JavaScript ICO encoder is certainly a possibility, no-one has yet written one.

  • Canvas Text To draw text, Faviconist uses Canvas’s fillText method. e.g. context = canvas.getContext('2d'); context.fontStyle = '25px arial'; context.fillText('Yo!'). When Ace Editor effort got started (called Bespin), in the early days of canvas, text support was patchy. But now it’s very well supported.

  • MeasureText Library I thought Faviconist would be easy because I thought there would be simple metrics for fonts. Turns out canvas’s measureText() returns a “TextMetrics” object, and guess what TextMetrics contains:

interface TextMetrics {
  readonly attribute double width;
};

Huh? We can only find the text’s width, not its height. And as a I went down the path, I learned you can’t just say “draw this text with its top-left at (0,0)”. To center the font, as we do in Faviconist, we actually need to determine text offset as well – left and top.

So I built the MeasureText library. It works as a drop-in replacement (~shim) for the built-in HTML5 Canvas MeasureText mechanism, and also provides a new convenience function not requiring an existing canvas. It works by drawing the text and scanning the resulting bitmap to get a true representation of the metrics. Using this, and with a little geometry, it’s possible to center text.

  • Favicon Library Figured it would be cool to show a preview of the favicon by changing the site’s actual favicon! For which I used ye olde Favicon library, which I originally created via this blog and I’ve now officially moved to Faviconist.com. The library also incorporates a new “badge” feature, so you can show number of pending emails, etc. Go try the demo!

  • Font Selection You can choose fonts, with the fonts coming from the Google Font Directory. It wasn’t feasible load all fonts, so they’re loaded dynamically, but I wanted to show previews … so there’s a script to build a 38,000 pixel sprite map! It’s loaded after the page loads, with a canvas-based check to see if it loaded successfully (since it doesn’t work on Firefox). To show it in a dropdown, I used a fork of the Chosen library, a fork which retains the class of each option in the select list.

  • Chrome Frame Didn’t want to support IE6-IE8, so introduced Google Chrome Frame, based on the code in HTML Boilerplate, but increasing the version check from 6 to 8.

  • JavaScript Libraries Faviconist uses several useful libraries: jQuery, Underscore, Backbone, and jQuery Tools. And just to say, jQuery Tools is the very picture of Developer Experience heaven. Great explanations, many easy-to-follow demos, lots of options…and a CDN for the libraries.

  • NodeJS, Connect, Express The server is NodeJS running the Express-Connect stack. Considering that the app is almost all client-side, I spent a ton of time getting up to speed with this stack, partly due to performance optimisatins, and partly due to the next point …

  • Jade, Stylus, Kaffeine Being a fan of DRY, I’m very happy to be using higher-level abstractions of HTML, CSS, and JavaScript. I certainly am happy with Jade, with the exception of dropping in raw HTML script snippets. And Stylus is absolutely awesome. Kaffeine makes JavaScript much easier, though I’ve found it difficult to incorporate everywhere because the ecosystem is very much geared around CoffeeScript. e.g. Connect comes with a default CS compiler, Nodemon (a node watch-and-run-tool by Remy Sharp) supports CS, there’s a ton of doco about getting CS working with things. So that was really the biggest challenge. I mainly wanted Kaffeine because I’m not such a fan of significant whitespace, but the ecosystem’s preference for CoffeeScript did present challenges.

I hope you enjoy Faviconist. It’s a work in progress, so please leave feedback if you have suggestions.

Dynamic Favicon Library Updated

Ajax, AjaxPatterns, Favicon, HTML, Javascript, Web, Web 2.0

I updated the favicon library a while ago, for a couple of projects I haven’t released for various reasons. Anyway, Phil asked me about it, so I thought it’s a good time to package it up and release it properly. And in the process wrote up Taking Browser Tabs Seriously which has also been on the backburner.

The main point of this library is to update the favicon via Javascript, but at a higher level, its main objective is to provide some support for notifying the user of events in another tab. For example, if you start playing music in another tab, you can make a one-liner call to change the favicon to a sound. Or if you really need to alert the user, you can start animating it.

See the original post for more info. The new features are:

  • Scrolling title. The window/tab title scrolls. (Title blink is coming. No, really!)
  • Stop functions. unanimate() and unscroll() will stop animation and scrolling, respectively. Previously you had to do stop animation indirectly, by calling change().
  • Rails/Scriptaculous style options Changed config to be fn(mainarg, optionalHash). Read the library or demo source to see the details.

Demos:

API (also in the code):

javascript

  1. favicon.change("/icon/active.ico", "new title"); // Cancels any animation/scrolling
  2.     favicon.change("/icon/active.ico"); // leaves title alone. Cancels any animation.
  3.     favicon.change(null, "new title"); // leaves icon alone. Cancels any scrolling.
  4.  
  5.     favicon.animate(["icon1.ico", "icon2.ico", ...]);
  6.     favicon.animate(["icon1.ico", "icon2.ico", ...], {delay: 500} );
  7.       // Tip: Use "" as the last element to make an empty icon between cycles.
  8.       // Default delay is 2000ms
  9.     // animate() cancels any previous animation
  10.  
  11.     favicon.scrollTitle("new title");
  12.     favicon.scrollTitle("new title", { delay: 200, gap: "------"} )
  13.       // delay is delay between each scroll unit
  14.       // gap is string appended to title (default: "      ")
  15.     // scrollTitle() cancels any previous scrolling
  16.  
  17.     favicon.unscroll();
  18.  
  19.     favicon.unanimate();

Maybe in another two years, I’ll update it again. The main enhancement would be to combine it with audio notifications (with or without Flash, depending on the browser). So you could make a single call that (a) changes favicon; (b) scrolls the title; (c) plays a sound. Now that will get their attention!!!

Taking Browser Tabs Seriously

I’ve just updated my favicon library, which I first wrote about here. I’ll explain more about the update in a separate post. For now, I want to talk about browser tabs.

Browser tabs were introduced by Opera. Then Firefox adopted them a few years later, as did Safari. Then Microsoft stepped into the ’90s with their own IE tabs. Meanwhile, tabs became teh coolness and Kevin and Alex joked on Diggnation about how you could get brownie points by saying it’s a tabbed interface. And so you get tabbed terminals among other things, and fortunately there is some consistency on keyboard shortcuts (typically ctrl-t to make a new tab and ctrl-w to close it, or option-t/w on mac).

We’ve outgrown the rudimentary functionality that is available for managing tabs.

The browser is the new operating system, the tab is the new system process, the tab bar is the new taskbar.

Power users struggle to keep up with 20+ browser tabs and grasp what’s inside them. The Firefox Tab Mix extension is a superb addition and should be part of the core. But there is a lot more that could be done, for instance:

  • Notifications. The whole issue of attention and notifications needs re-thinking in light of the new world of rich web apps. Quintessential example is web chat – how do you inform the user someone has sent a message, in another window? The favicon library helps here, and the update in my next post, helps a bit more. Playing a sound is also possible. Still, I would like to see API support for ambient dialogs, like Growl/Snarl and the Windows “sunrise” notfier that emerges from the taskbar (what’s it called officially?). And sound. It’s 2008, why can’t browsers issue a single beep like a good 1970s PC, without requiring flash or unreliable hacks!!! Speaking of sound …
  • Where’s that sound coming from? There’s a sound in my browser, but I don’t know where! Tabs should provide a visual indication if a sound is emerging from them.
  • Default/Custom Favicons. If a site doesn’t have a favicon, browsers show nothing. Bzzzt!!! They should provide more sensible defaults, e.g. at least show the site’s background colour or a thumbnail of the first image. Something to make them all different from each other.
  • Provide a Summary List. Like clicking on Ctrl-Alt-Delete in Windows to get a task list or “ps” in Unix. You’d be able to see how long each tab has been open, memory usage, other excitement.
  • Hover info Similar to the previous point, let web developers provide tooltip info which will be displayed as the user hovers over the tab.
  • Popup menus Why even open up a web page? Sometimes, you want to do something quickly without having to switch tabs. Let web developers create site-specific popup menus that emerge from the tab. For example, you could use this mechanism to record simple events as they occur. Or start and stop a timer. Or to switch channels on a music website.
  • COLOUR AND STUFF!!! Browser tabs are pretty dull – just an icon and some text. Using cues such as colour and font styles, the browser could say a lot more about what’s happening in the other tabs. Perhaps it could be set by the programmer or perhaps it could be set by the user (e.g. create a heatmap highlighting the least used tabs).
  • Javascript events. Javascript onEntered()/onExited() events to let the application know if it’s active or not. (Similar to what desktop apps receive.) This would be absolutely brilliant for when you are notifying the user about something they need to see (e.g. a new chat message) – once they re-enter the tab, you can switch off the notification.
  • Open Forms. What about when I start writing something in a form, then switch tabs, and forget which tab has the form, or forget that it’s there at all. The browser should indicate when there’s a form open that you’ve been writing to. (Though in some cases auto-backup features may mean that’s not necessary.)
  • Search. No-brainer. Browser search should work across all tabs, not just the one currently open. This would not only help you find some text, but also pinpoint one of the fifty tabs you have open.
  • Virtual Desktop. Maybe it sounds mad, but I’d like something similar to virtual desktop (“Spaces” for Mac-heads). ie Switch from “work” tabset to “social” tabset, etc.
  • Auto-remove. Instead of forcing me to close all windows, or some random subset, or restart the browser altogether, provide some support for removing the tabs that matter least. e.g. the tabs that I haven’t used for the longest and which I appear not to have interacted with (ie started editing a form), and/or the tabs that are taking up the most resources.

I’m sure there’s a lot more. The main point is to take inspiration from the way operating systems let users deal with open applications, and then some. The dynamic favicon library is a small part of the solution, but there’s only so much libraries and even browser add-ons can do…it needs to become a core feature of the browsers. Just as Opera and then Firefox owe a big chunk of their initial popularity to their the cult of the tab, so too do the manufacturers today have a similar opportunity to take it to the next level.

Dynamic Favicons

Favicons should ideally be easy to manipulate, as easy as manipulating the web page’s UI. (Favicons are the little website icons you see in the address bar, browser tabs, etc.) For example, a chat app like Meebo could signal that your buddy’s trying to contact you, a mail app like GMail could indicate You Have Mail!

I’ve found surprisingly little info on this – is anyone doing it? Anyway, I’ve been wanting to play around with this for a while and having recently submitted the final book draft (post pending), I finally had some spare time to play with it. Fortunately, it turns out to be perfectly feasible – it seems that Firefox and Opera both use <link> tags to determine favico, and this can be changed dynamically to satisfaction. The only gotcha is that you can’t try to be too efficient – if you reuse an existing link object and overwrite its href property, the browsers won’t pay any attention. so you simply have to remove the existing link tag and add back a new one with the new icon URL. Unfortunately, IE and Safari don’t seem to use the link technique at all – I think they just use the “favicon.ico” file. If you know of a way their icons could be dynamically manipulated, please mail me or add a comment here.

So I’ve created a library, favicon.js, that lets you manipulate favicons with a single call – changeFavicon("theIconUrl.ico");. You can also set the document title, changeFavicon("theIconUrl.ico", "Hi Everybody!"), which just sets document.title. There are a couple of demos and a brief FAQ:

Ajaxify favicon demo

Implementation Details. Here’s the favicon.js code as it stands, all 32 lines of it :-).

javascript

  1. var favicon = {
  2.  
  3. change: function(iconURL) {
  4.   if (arguments.length==2) {
  5.     document.title = optionalDocTitle;
  6.   }
  7.   this.addLink(iconURL, "icon");
  8.   this.addLink(iconURL, "shortcut icon");
  9. },
  10.  
  11. addLink: function(iconURL, relValue) {
  12.   var link = document.createElement("link");
  13.   link.type = "image/x-icon";
  14.   link.rel = relValue;
  15.   link.href = iconURL;
  16.   this.removeLinkIfExists(relValue);
  17.   this.docHead.appendChild(link);
  18. },
  19.  
  20. removeLinkIfExists: function(relValue) {
  21.   var links = this.docHead.getElementsByTagName("link");
  22.   for (var i=0; i&lt;links .length; i++) {
  23.     var link = links[i];
  24.     if (link.type=="image/x-icon" && link.rel==relValue) {
  25.       this.docHead.removeChild(link);
  26.       return; // Assuming only one match at most.
  27.     }
  28.   }
  29. },
  30.  
  31. docHead:document.getElementsByTagName("head")[0]
  32. }

Update (Two Days Later)

Crikey! Dugg and on Delicious Popular. And, well, Ajaxian too ;-). Digg is interesting … The last time I submitted my own story to digg, it got precisely two diggs (thanks to the other guy!). This time, I didn’t bother. Is there a moral here?

New, improved, with animate(). Most people get dynamic favicons, but some people have said this whole thing is about animation, about as useful as a blink tag, etc. Okay, that kind of misses the main point, which is about notifying the user while a tab is in the background. The FAQ makes it pretty clear that animated icons was a kind of afterthought (actually, it only occurred to me after I created the cycling demo – changing according to a timer was simply the easiest way to update a background tab, since there’s no chat functionality needed or anything like that). But, you know, when a simple idea like that causes seems so wrong to some people, there’s probably wheels in it. And while I did say animated GIFs are possibly more elegant in the FAQ, it since occurred to me that it’s a bit of a hassle for the casual developer to make an animated GIF. You also get the benefit of compatibility with Opera (and maybe others?). So I’ve added an animate() method, only 8 more lines in all, that lets you cycle through a sequence of images. I expect to post it over the weekend. Mmm…Eye Candy!