Search code examples
permissionsgoogle-chrome-extensionfavicon

Reliably getting favicons in Chrome extensions, chrome://favicon?


I'm using the chrome://favicon/ in my Google Chrome extension to get the favicon for RSS feeds. What I do is get the base path of linked page, and append it to chrome://favicon/http://<domainpath>.

It's working really unreliably. A lot of the time it's reporting the standard "no-favicon"-icon, even when the page really has a favicon. There is almost 0 documentation regarding the chrome://favicon mechanism, so it's difficult to understand how it actually works. Is it just a cache of links that have been visited? Is it possible to detect if there was an icon or not?

From some simple testing it's just a cache of favicons for pages you have visited. So if I subscribe to dribbble.com's RSS feed, it won't show a favicon in my extension. Then if I visit chrome://favicon/http://dribbble.com/ it won't return right icon. Then I open dribbble.com in another tab, it shows its icon in the tab, then when I reload the chrome://favicon/http://dribbble.com/-tab, it will return the correct favicon. Then I open my extensions popup and it still shows the standard icon. But if I then restart Chrome it will get the correct icon everywhere.

Now that's just from some basic research, and doesn't get me any closer to a solution. So my question is: Is the chrome://favicon/ a correct use-case for what I'm doing. Is there any documentation for it? And what is this its intended behavior?


Solution

  • There is now the official documentation for Favicon Permission - Fetching favicons.

    Add favicon to your permission

    {
      "name": "Favicon API in a popup",
      "manifest_version": 3,
      ...
      "permissions": ["favicon"],
      ...
    }
    

    Access the favicon URL

    For my simple case:

    const favIconUrl = `chrome-extension://${chrome.runtime.id}/_favicon/?pageUrl=${encodeURIComponent(url)}&size=32`;
    

    From their example:

    function faviconURL(u) {
      const url = new URL(chrome.runtime.getURL("/_favicon/"));
      url.searchParams.set("pageUrl", u);
      url.searchParams.set("size", "32");
      return url.toString();
    }
    
    const img = document.createElement('img');
    img.src = faviconURL("https://www.google.com") 
    document.body.appendChild(img);
    

    This also works on Chromium Edge, it automatically transform chrome-extension:// into extension://

    Note: when fetching favicons in content scripts, the "_favicon/*" folder must be declared as a web accessible resource. For example:

      "web_accessible_resources": [
        {
          "resources": ["_favicon/*"],
          "matches": ["<all_urls>"],
          "extension_ids": ["*"]
        }
      ]