Build Dynamic Favicon with JavaScript

Eugene Musebe

Introduction

A favicon is a small image displayed next to the page title in the browser tab. It creates a visual representation of your website and saves time by allowing users to easily identify your brand with it. Establishing brand recognition through favicons is important for Search Engine Optimization. You may have noticed that modern web applications have dynamic favicons that change over time.

In this article, we will explore how we can build a dynamic favicon with JavaScript.

Github

Check out the complete source code in this GitHub Repository.

Codesandbox

The final project can be viewed on Codesandbox.

Pre-requisites

To effectively follow along through this article you are required to have:

  • Basic HTML5 skills

  • Basic knowledge of JavaScript

Introduction

In this demo, we are going to create favicons that change after a specific time, say after one second. Later we are going to create a simple favicon with a static notification by using HTML canvas to draw on it. Most of the favicons have a common name favicon.ico

HTML canvas is an element that can be used to draw graphics on a web page via scripting (usually JavaScript)

A favicon is a square image with sizes of 16*16 and supports a variety of file formats including .ico, .png, .gif, .jpeg and .svg In this article we are going to use .png files.

Sounds interesting, right?

Project Setup

Open an empty folder in your favorite text editor and create a folder we are going to store our at least two favicon images. Then create an index.html inside the parent folder and paste the following.

1<!DOCTYPE html>
2
3<html lang="en">
4
5<head>
6
7<meta charset="UTF-8">
8
9<meta http-equiv="X-UA-Compatible" content="IE=edge">
10
11<meta name="viewport" content="width=device-width, initial-scale=1.0">
12
13<title>Dynamic Favicons</title>
14
15<link id="favicon" rel="icon" href="favicons/0.png" type="image/png" sizes="16*16">
16
17</head>
18
19<body>
20
21<h1 style="text-align: center; color: crimson;">Welcome to Cloudinary</h1>
22
23<p style="text-align: center; margin: auto; width: 60%;">Transform images and videos to load faster with no visual degradation, automatically generate image and video variants, and deliver high quality responsive experiences to increase conversions.</p>
24
25
26
27<script src="script.js"></script>
28
29</body>
30
31</html>

Right-click the index.html file and open it in your browser. You should be able to see a page and besides the title Dynamic Favicons a favicon of your choice. It should look like this. We can then look at this in more detail.

If you are using CodeSandbox you have to open the browser page in a new tab for you to see the page's favicon. To do this just click the top rightmost button on the browser section.

Add Favicon to your Web Page

To add a favicon for your page add a <link> element just after the title element. Ensure that you have the favicon image saved in the root directory of your project or inside a folder for this case the favicons folder. You can visit this link to create your own favicon.

1<link id="favicon" rel="icon" href="favicons/0.png" type="image/png" sizes="16*16">

You may also notice that here we are naming the favicons with numbers, this is to make iterating through the favicons easier, you'll see this in the next steps.

You can specify the size using the sizes attribute to ensure that they are of the right size i.e., 16*16.

Handle the Favicon element

Create a script.js file in your root folder because we are going to use JavaScript to handle the favicon once our page loads.

1window.onload = function () {
2
3var favicon = document.getElementById('favicon');
4
5}

We can create an animation effect for our favicon by changing it after every second. It is also clear here as to why we used ascending numbers to name our favicons. We will increment the faviconIndex after every second and this will change the URL of the link.

1window.onload = function () {
2
3
4
5var faviconIndex = 0;
6
7var favicon = document.getElementById('favicon');
8
9
10
11setInterval(function() {
12
13favicon.href = "favicons/"+faviconIndex + ".png";
14
15faviconIndex++;
16
17faviconIndex %= 3; // number of favicons (3)
18
19}, 1000);
20
21};

If you refresh your browser after saving the changes you will see the favicon changing after every second. You can do this to grab people's attention.

Create a Favicon with a simple notification badge

In this second part, we are going to create our own simple favicon with a static notification. We will use HTML Canvas to create a favicon and display some text on it. This code is in the badge.js file. You can either replace the script.js with this or reference a new js file in your index.html file.

1window.onload = function(){
2
3var favicon = document.getElementById('favicon');
4
5var faviconSize = 16;
6
7var canvas = document.createElement('canvas');
8
9var context = canvas.getContext('2d');
10
11var img = document.createElement('img');
12
13img.src = favicon.href;
14
15
16
17img.onload = () => {
18
19canvas.width = faviconSize;
20
21canvas.height = faviconSize;
22
23context.fillStyle = "#F76B67";
24
25context.fillRect(0, 0, canvas.width, canvas.height);
26
27context.font = "10px 'helvetica', Assistant";
28
29context.fillStyle = "#FFFFFF";
30
31context.textAlign = "center";
32
33context.textBaseline = "middle";
34
35context.fillText(3, canvas.width - faviconSize / 3, faviconSize / 3 );
36
37favicon.href=canvas.toDataURL("image/png");
38
39};
40
41}

To get a drawing context on the canvas we use the HTMLCanvasElement.getContext() method and takes a contextType parameter getContext(contextType) for our case "2d" which leads to the creation of an object representing a two-dimensional rendering context.

1const context = canvas.getContext("2d");

We can also specify the height pixels and width pixels of our canvas element by using the height and width attribute of the canvas element created. Since the favicon takes a width of 16 we'll use the favicon size.

1canvas.width = faviconSize;
2
3canvas.height = faviconSize;

We can then draw our background by first setting the background color by using the fillStyle property and then drawing a filled rectangle with the background set.

The fillStyle canvas property sets the color used in filling the drawing.

The fillRect() method draws a filled rectangle. The default background color is black.

The fillRect() takes four parameters, the x-coordinate of the upper corner of the rectangle, the y-coordinate of the upper corner of the rectangle, and the width of the rectangle in pixels, and the height of the rectangle in pixels.

1context.fillStyle = "#F76B67";
2
3context.fillRect(0, 0, canvas.width, canvas.height);

Draw the notification text

We can also add some text on the canvas element and place it on the top right so that it looks like a notification. We will specify the font, color, and alignment and set the baseline of the text as shown below.

1context.font = "10px 'helvetica', Assistant";
2
3context.fillStyle = "#FFFFFF";
4
5context.textAlign = "center";
6
7context.textBaseline = "middle";

To draw the text we use the fillText method which takes three parameters: the text, x-coordinate, and y-coordinate. The coordinates are used to place the text in a certain part, for our case we are going to align it to the top right.

1context.fillText(3, canvas.width - faviconSize / 3, faviconSize / 3 );

We then change the favicon link so that it displays the canvas element we have created. toDataURL is a canvas method that returns the data URL of the canvas image.

1favicon.href=canvas.toDataURL("image/png");

Conclusion

In conclusion, we have learned how we can create a simple dynamic favicon that changes after a specified time. Another interesting thing we have learned is how we can create a simple favicon using HTML canvas.

Some other cool thing you can create is a favicon with animated badges. We will cover how we can achieve this in yet another article.

Eugene Musebe

Software Developer

I’m a full-stack software developer, content creator, and tech community builder based in Nairobi, Kenya. I am addicted to learning new technologies and loves working with like-minded people.