Search code examples
javascriptimagewebpresponsive-imagesavif

How to check if the browser supports AVIF images


How can I detect if the browser supports AVIF images using JavaScript? I have viewed this question and after reading the answers I was able to build a useful one-liner function to check browser support for various image types.

const isSupported = (type) => document.createElement('canvas').toDataURL(`image/${type}`).indexOf(`data:image/${type}`) === 0;

And it works fine for webp (and jpeg & png) images. But it's not working for avif (and gif) images.

By the word Not working, I mean the function is returning false even if the browser supports AVIF images.

So, what is wrong with this approach? And what is the correct way to detect browser support for avif images using JavaScript?


Solution

  • as far as I can tell, the browser can't create AVIF, JXL or GIF files with the toDataURL method out of a canvas. I currently use the following method to detect AVIF support via Javascript:

    var avif = new Image();
    avif.src = "data:image/avif;base64,AAAAIGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZk1BMUIAAADybWV0YQAAAAAAAAAoaGRscgAAAAAAAAAAcGljdAAAAAAAAAAAAAAAAGxpYmF2aWYAAAAADnBpdG0AAAAAAAEAAAAeaWxvYwAAAABEAAABAAEAAAABAAABGgAAAB0AAAAoaWluZgAAAAAAAQAAABppbmZlAgAAAAABAABhdjAxQ29sb3IAAAAAamlwcnAAAABLaXBjbwAAABRpc3BlAAAAAAAAAAIAAAACAAAAEHBpeGkAAAAAAwgICAAAAAxhdjFDgQ0MAAAAABNjb2xybmNseAACAAIAAYAAAAAXaXBtYQAAAAAAAAABAAEEAQKDBAAAACVtZGF0EgAKCBgANogQEAwgMg8f8D///8WfhwB8+ErK42A=";
    avif.onload = function () {
     /* do something * /
    };
    

    Another approach would be using a promise:

      new Promise(() => {
        const image = new Image();
        image.onerror = () => /* do something */
        image.onload = () => /* do something */
        image.src =
          "data:image/avif;base64,AAAAIGZ0eXBhdmlmAAAAAGF2aWZtaWYxbWlhZk1BMUIAAADybWV0YQAAAAAAAAAoaGRscgAAAAAAAAAAcGljdAAAAAAAAAAAAAAAAGxpYmF2aWYAAAAADnBpdG0AAAAAAAEAAAAeaWxvYwAAAABEAAABAAEAAAABAAABGgAAAB0AAAAoaWluZgAAAAAAAQAAABppbmZlAgAAAAABAABhdjAxQ29sb3IAAAAAamlwcnAAAABLaXBjbwAAABRpc3BlAAAAAAAAAAIAAAACAAAAEHBpeGkAAAAAAwgICAAAAAxhdjFDgQ0MAAAAABNjb2xybmNseAACAAIAAYAAAAAXaXBtYQAAAAAAAAABAAEEAQKDBAAAACVtZGF0EgAKCBgANogQEAwgMg8f8D///8WfhwB8+ErK42A=";
      }).catch(() => false);
    

    We create a new Image with the smallest source possible and try to load it. This works reliably and tested on Firefox, Edge, IE, Chrome, Opera & Safari, including mobile support. Maybe you can create a oneliner for your intentions out of it! I'd love to see smarter and leaner approaches to check for AVIF support.

    Sources:

    1. https://avif.io/blog/tutorials/css/#avifsupportdetectionscript
    2. https://github.com/leechy/imgsupport/blob/master/imgsupport.js
    3. https://github.com/justinschmitz97/avif.io/blob/master/components/Layout/Header.tsx