DEV Community

Loftie Ellis
Loftie Ellis

Posted on • Originally published at blog.pagewatch.dev

1

Finding the largest favicon with js

As part of an audit I wanted to fetch the highest quality favicon for every page that we check. It turned out to be slightly more complicated than I thought:

These stackoverflow posts suggest a few ways to get the favicon, but they all share a few issues:

  • It depends on a 3rd party (eg Google)

  • It ignores the default /favicon.ico, or uses it incorrectly

  • It returns the first favicon, instead of the largest one

How the browser chooses a favicon

The standard way to include a favicon is with a link tag <link rel="icon".. You can use multiple link tags to specify different sizes, for example:

<link rel="icon" sizes="16x16" href="/favicon_16.png">
<link rel="icon" sizes="32x32" href="/favicon_32.png">
Enter fullscreen mode Exit fullscreen mode

Another popular variant is <link rel="shortcut icon"..

<link rel="shortcut icon" href="/favicon_32.png">
Enter fullscreen mode Exit fullscreen mode

If none of these tags are present the browser will make a request to the /favicon.ico file at the root directory. Some servers are badly configured though and will return an 200 OK status even if the file is not present, so to be sure you have to check that the file is indeed an image.

The solution

The following codes combines all these factors, and loops through the available favicons to return the largest one.

// Get the largest favicon in the current document, or false if none is found.
let getLargestFavicon = async () => {
  let getSize = el => {
    return (el.sizes[0] && parseInt(el.sizes[0], 10)) || 0;
  };
  let favicons = [
    ...document.querySelectorAll('link[rel="shortcut icon"],link[rel="icon"]')
  ].sort((a, b) => {
    return getSize(b) - getSize(a);
  });
  if (favicons.length > 0) {
    return favicons[0].href;
  }
  // no favicon is specified in the meta tags, lets try the default /favicon.ico
  let defaultLocation = document.location.origin + "/favicon.ico";
  let r = await fetch(defaultLocation);
  if (r.ok) {
    let t = await r.blob();
    if (t.type.indexOf("image") !== -1) {
      return defaultLocation;
    }
  }
  return false;
};
Enter fullscreen mode Exit fullscreen mode

Originally published at https://blog.pagewatch.dev/post/finding-the-largest-favicon-with-js

Heroku

Build apps, not infrastructure.

Dealing with servers, hardware, and infrastructure can take up your valuable time. Discover the benefits of Heroku, the PaaS of choice for developers since 2007.

Visit Site

Top comments (0)

Cloudinary image

Zoom pan, gen fill, restore, overlay, upscale, crop, resize...

Chain advanced transformations through a set of image and video APIs while optimizing assets by 90%.

Explore

👋 Kindness is contagious

Please leave a ❤️ or a friendly comment on this post if you found it helpful!

Okay