1

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')
    }
Node Shack
  • 59
  • 6

1 Answers1

0

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...

Node Shack
  • 59
  • 6
Ben Carey
  • 16,540
  • 19
  • 87
  • 169
  • How does this solve the lack of internet connection preventing the load of the grayed out favicon? Wouldn't you need to load the image prior to the disconnect (so I assume on page load?) – TCooper Jul 01 '19 at 23:18
  • @TCooper - ah, #bugger - I didn't see that part of the question... I will amend to include a preload for the image – Ben Carey Jul 01 '19 at 23:20
  • var favicon = document.getElementById('favicon'); var faviconSize = 16; var canvas = document.createElement('canvas'); canvas.width = faviconSize; canvas.height = faviconSize; var context = canvas.getContext('2d'); var img = document.createElement('img'); img.src = favicon.href; img.onload = () => { context.drawImage(img, 0, 0, faviconSize, faviconSize); var offline_href = canvas.toDataURL('image/png'); }; – TCooper Jul 01 '19 at 23:25
  • @TCooper - see updated answer. I haven't tested it but the core is there and should provide enough reference for the OP – Ben Carey Jul 01 '19 at 23:36
  • @TCooper haha, it wouldn't be hard, the above is just a rough example, it could be done 1000x better. I will clean it up if I get a moment – Ben Carey Jul 01 '19 at 23:39