I am trying to set different icons for when my browser is online(Normal logo) and offline(Greyed out logo). I am using Vue JS and I am able to detect online and offline set, I am also able to set different favicon for the different state but the offline icon won't show because my browser does not have internet to fetch the icon.
What is the best approach to achieve this? The code I am using is below, btw I am using 'v-offline' to detect online or offline states
handleConnectivityChange (status) {
status ? $('#favicon').attr('href', 'https://snackify-cdn.sfo2.digitaloceanspaces.com/favicon-on.png') : $('#favicon').attr('href', 'https://snackify-cdn.sfo2.digitaloceanspaces.com/favicon-off.png')
}
There are two elements to this, preloading the favicons, and setting them dynamically.
The first part can be achieved in various ways. I would opt for the Vue created
method as you could show a spinner on the page until the component is mounted
. This would probably be better suited as a mixin, instead of directly on the component.
data() {
return {
favicons: {} // we need to store the images to prevent the browser releasing them
}
},
created () {
// This can be improved but the logic is here
// Create the JS images
this.favicons = {
'online': new Image(),
'offline': new Image()
};
// Set the source properties
this.favicons.online.src = 'https://snackify-cdn.sfo2.digitaloceanspaces.com/favicon-on.png';
this.favicons.offline.src = 'https://snackify-cdn.sfo2.digitaloceanspaces.com/favicon-off.png';
}
Then, to update the favicon, you can do something along the lines of the following:
handleConnectivityChange (status) {
// Get or create the favicon
let link = document.querySelector("link[rel*='icon']") || document.createElement('link');
// Set the attributes of the favicon
link.type = 'image/x-icon';
link.rel = 'shortcut icon';
link.href = status ? this.favicons.online.src : this.favicons.offline.src;
// Append the favicon to the `head`
document.getElementsByTagName('head')[0].appendChild(link);
}
Credit to: Changing website favicon dynamically
As a side note, and this is just my opinion, I would advise dropping jQuery if you are using Vue. There is very little need for it and it just adds to the overhead. In the scenario here, you can very easily use vanilla JS to achieve what you need as the example demonstrates...