Change Favicon based on the application state

Published: 29 June 2018


Introduction

GitHub has a great feature which communicates the status of a Pull Request by changing the Favicon of the page. In the screenshots below you can see examples of this.

When all checks have not yet completed:

All checks have not yet completed

When all checks have passed:

All checks have passed

When some checks have failed:

Some checks have failed

My blog post from yesterday which demonstrates how to communicate the status of a background job with SignalR is a great candidate for something like this. In this blog post, I will show how you can implement something similar to GitHub.

Creating status Favicons

First, I needed to find or create Favicons I can use to reflect the status of a background job. Font Awesome contains many icons which fit the bill, but first I needed to convert them into a format I can use as a Favicon.

I found the Font Awesome Favicon Generator which allowed me to do just this. It is as simple as finding an appropriate icon and downloading it as a PNG:

Font Awesome Favicon Generator

Changing the Favicon based on the status

To change the Favicon for a web page, I came across this Gist which demonstrates how to do it.

I updated the code from yesterday’s blog to also update the Favicon upon status change. The Favicon defaults to the waiting status. Once some progress is received, I change it to a running status and then finally, when the background job is complete, I change it to a done status:

document.head || (document.head = document.getElementsByTagName('head')[0]);

var connection = new signalR.HubConnectionBuilder()
    .withUrl("/jobprogress")
    .configureLogging(signalR.LogLevel.Information)
    .build();
connection.on("progress",
    (percent) => {
        if (percent === 100) {
            changeFavicon("/done.png");
            document.getElementById("job-status").innerText = "Finished!";
        } else {
            changeFavicon("/running.png");
            document.getElementById("job-status").innerText = `${percent}%`;
        }
    });
connection.start()
    .then(_ => connection.invoke("AssociateJob", "@ViewBag.JobId"))
    .catch(err => console.error(err.toString()));

changeFavicon("/waiting.png");

function changeFavicon(src) {
    var link = document.createElement('link'),
        oldLink = document.getElementById('dynamic-favicon');
    link.id = 'dynamic-favicon';
    link.rel = 'shortcut icon';
    link.href = src;
    if (oldLink) {
        document.head.removeChild(oldLink);
    }
    document.head.appendChild(link);
}

Here are some screenshots of the updated application in action, demonstrating each of these states. Note the different Favicon in each screenshot.

Background job is waiting

Background job is running

Background job is complete

If you found value in this blog post and want to return the favour, you can Buy me a coffee

PS: I publish a weekly newsletter for ASP.NET Developers called ASP.NET Weekly. If you want to get an email every Friday with all the best ASP.NET related blog posts from the previous week, please sign up!