the difference between Tab.faviconUrl and favicon API

996 views
Skip to first unread message

Lu Xu

unread,
Aug 5, 2022, 7:44:08 PM8/5/22
to Chromium Extensions
Hi team,
I tried this new API in MV3 on Chrome Canary 106: chrome-extension://${chrome.runtime.id}/_favicon/?pageUrl=${encodeURIComponent(url)}&size=64, and it works fine
Also, I notice the Tab object also contain a favIconUrl, document here https://developer.chrome.com/docs/extensions/reference/tabs/#type-Tab

From my experiments, these two approaches return different results

The favicon API returns a worse result in some circumstances, despite we can specify the size, however, the Tab.favIconUrl returns a much better result.
For example:
Netflix: Tab.favIconUrl is https://assets.nflxext.com/us/ffe/siteui/common/icons/nficon2016.ico, which is much better than chrome-extension://<id>/_favicon?pageUrl=https%3A%2F%2Fwww.netflix.com&size=64
Github: https://github.githubassets.com/favicons/favicon.svg is much better than favicon API with size=64

Another interesting finding is if you visit a website for the first time, both Tab.favIconUrl and favicon API will give you correct result immediately, you need to refresh that website and give Chrome sometime, then you will have the icon. Is this expected?

So which approach should I use? (my extension can add both Tab and favicon permission), it seems Tab.favIconUrl is always offering higher quality images, but I suppose the favicon API will not have the CORS issue while it is not guaranteed for  Tab.favIconUrl

Thank you very much

wOxxOm

unread,
Aug 6, 2022, 1:51:25 AM8/6/22
to Chromium Extensions, thus...@gmail.com
The API implementation still may have bugs, or at least it's something that could be improved, so I suggest you to open a bug report on https://crbug.com.

hrg...@gmail.com

unread,
Aug 6, 2022, 2:13:11 AM8/6/22
to Chromium Extensions, thus...@gmail.com
The new chrome-extension://<EXT_ID>/_favicon/ probably uses the same underlying mechanism of the old chrome://favicon/ API.

The old API gets the icon from the browser's local repository of icons. Therefore, it has a number of advantages:
  1. It works without an internet connection  
  2. It's much faster than getting the icon from the original source
  3. It works for all bookmarked URLs even if those URL don't exist anymore
  4. It gives a rasterised version of the icon

Jackie Han

unread,
Aug 6, 2022, 2:23:47 AM8/6/22
to hrg...@gmail.com, Chromium Extensions, thus...@gmail.com
From a developer's point of view, MV2 chrome://favicon/ is easier to use.

--
You received this message because you are subscribed to the Google Groups "Chromium Extensions" group.
To unsubscribe from this group and stop receiving emails from it, send an email to chromium-extens...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/chromium-extensions/2b9b01c3-f5cf-4899-93f4-0a78c21edfb4n%40chromium.org.

Lu Xu

unread,
Aug 6, 2022, 3:18:43 AM8/6/22
to Jackie Han, hrg...@gmail.com, Chromium Extensions
Thanks all, currently I care about the icon quality the most, so I would like to choose the approach that gives the best image, as hrg pointed out, the favicon API has a lot advantages, I would like to use the favicon API if it always provide same or better quality
Another advantage of the new API is we can use fetch to get the image response directly, and no need to worry about CORS, while you can not use fetch for `chrome://favicon`
Admittedly, someone may still prefer 16*16 image since it is a typical favicon.ico, so maybe if you don't provide size parameter, it will return favicon.ico, if you provide the size, hopefully chrome will return the image that closest to the size. I can create a ticket for this


hrg...@gmail.com

unread,
Aug 6, 2022, 6:59:41 PM8/6/22
to Chromium Extensions, Jackie Han, Chromium Extensions, thus...@gmail.com, hrg...@gmail.com
On Saturday, August 6, 2022 at 2:23:47 AM UTC-4 Jackie Han wrote:
From a developer's point of view, MV2 chrome://favicon/ is easier to use.

Why?
The new MV3 API is also a URL that you can use exactly like chrome://favicon/.

Jackie Han

unread,
Aug 7, 2022, 2:50:41 AM8/7/22
to hrg...@gmail.com, Chromium Extensions, thus...@gmail.com
In Manifest V2
// manifest.json
{
  "permissions": ["chrome://favicon/"]
}
// utils.js
function getFaviconUrl(url) {
  return 'chrome://favicon/size/16@2x/' + url;
}


In Manifest V3
// manifest.json
{
  "permissions": ["favicon"]
}
// utils.js
function getFaviconUrl(url) {
  return `chrome-extension://${chrome.runtime.id}/_favicon/?pageUrl=${encodeURIComponent(url)}&size=32`;
}
// or
function getFaviconUrl(url) {
  let faviconUrl = new URL(`chrome-extension://${chrome.runtime.id}/_favicon/`);
  faviconUrl.searchParams.append('pageUrl', url);
  faviconUrl.searchParams.append('size', '32');
  return faviconUrl.href;
}


First, I stand on the developer's point of view, regardless of its internal implementation.
The old function getFaviconUrl() is a little easier than the new one.

Second, if browser supply a function to do it, e.g. chrome.runtime.getFaviconUrl(url, size) , developers don't need to pay attention to implementation details and don't have to change code from MV2 to MV3, MV4, MV5...

But what I want to express is not this little change in the code. What I want to say is that it is very important for developers to keep the platform stable and backward compatible. I hope that my extensions can be used by users for a long time without modification. If I have an accident or die one day, users can continue to use them for many years. If a platform must be overhauled every few years or has a lot of incompatible changes that require developers to make a lot of changes to make it continue work, this means that developers' time and lives are worthless (developers' time is not valued and is not a priority), and many good extensions will disappear in short years.

For example, the operating system binary executable file format, Java JDK and Java VM are very stable, very old programs can be run without modification. In addition, the standardized Web API is also very stable, and browsers are very cautious about making incompatible changes. However, the extension API is not standardized and is not treated as Web standards.

I think the easiest way for developers to do this(show favicon images) is backwards compatibility, so that developers do not need to modify anything and do not need to learn anything new. If developers need new features that are not supported by old APIs, then just design a new API for the new feature, so that the developers who need these new features will be happy to learn it.

wOxxOm

unread,
Aug 7, 2022, 2:55:58 AM8/7/22
to Chromium Extensions, Jackie Han, Chromium Extensions, thus...@gmail.com, hrg...@gmail.com
As a side note, when using the icons in an extension page with chrome-extension:// URL there's no need to prefix the URLs with chrome-extension://id, we can use relative paths:

  img.src = `/_favicon/?pageUrl=${encodeURIComponent(url)}&size=32`
  img.src = `/_favicon/?${new URLSearchParams({ pageUrl: url, size:32 })}`  

Jackie Han

unread,
Aug 7, 2022, 3:07:22 AM8/7/22
to wOxxOm, Chromium Extensions, thus...@gmail.com, hrg...@gmail.com
Thanks, that is more concise.

// used in extension pages, not for web_accessible_resources
function getFaviconUrl(url) {
  return `/_favicon/?pageUrl=${encodeURIComponent(url)}&size=32`;
}

hrg...@gmail.com

unread,
Aug 7, 2022, 3:49:55 AM8/7/22
to Chromium Extensions, Jackie Han, Chromium Extensions, thus...@gmail.com, hrg...@gmail.com
On Sunday, August 7, 2022 at 2:50:41 AM UTC-4 Jackie Han wrote:
But what I want to express is not this little change in the code. What I want to say is that it is very important for developers to keep the platform stable and backward compatible.

I agree with everything you said in those paragraphs. Maintaining backwards compatibility is important. However, MV3 is such a massive breakage with respect to MV2 that I don't see the point in worrying about the simple change of the favicon API.
Its like worrying that your face got wet in the middle of a flood.

Jackie Han

unread,
Aug 7, 2022, 4:01:08 AM8/7/22
to hrg...@gmail.com, Chromium Extensions, thus...@gmail.com
I'm not worried about it. Just saying that zero modification is always the easiest/simplest way.

Jackie Han

unread,
Aug 7, 2022, 4:32:50 AM8/7/22
to hrg...@gmail.com, Chromium Extensions, thus...@gmail.com
Add one note: This feature landed in Chrome 104 stable.
Chrome 104 supports both "pageUrl" and "page_url", but Chrome 105+ only supports "pageUrl".

Lofty Shaky

unread,
Aug 7, 2022, 5:38:31 AM8/7/22
to Chromium Extensions, Jackie Han, Chromium Extensions, thus...@gmail.com, hrg...@gmail.com
Is it possible to use this api in the content script? It gives me web_accessible_resources error.

wOxxOm

unread,
Aug 7, 2022, 5:48:21 AM8/7/22
to Chromium Extensions, bags...@gmail.com, Jackie Han, Chromium Extensions, thus...@gmail.com, hrg...@gmail.com
It's probably not implemented because chrome://favicon wasn't available there as well. You can suggest it on https://crbug.com.

Lofty Shaky

unread,
Aug 7, 2022, 5:53:26 AM8/7/22
to Chromium Extensions, wOxxOm, Lofty Shaky, Jackie Han, Chromium Extensions, thus...@gmail.com, hrg...@gmail.com
Thanks for response.

Jackie Han

unread,
Aug 7, 2022, 6:15:17 AM8/7/22
to Lofty Shaky, Chromium Extensions, thus...@gmail.com, hrg...@gmail.com
Is it possible to use this api in the content script? It gives me web_accessible_resources error.
In my test, it works successfully in content scripts. Remember to reload your extension after modifying manifest.json

// manifest.json
{
  "web_accessible_resources": [
    {
      "resources": [ "/_favicon/*" ],
      "matches": [ "<all_urls>" ]
    }
  ],
}
// content script, for example
function insertFavicon(url) {
  let favicon =document.createElement('img');
  favicon.src = `chrome-extension://${chrome.runtime.id}/_favicon/?pageUrl=${encodeURIComponent(url)}&size=32`;
  document.body.appendChild(favicon);
}
insertFavicon('https://www.google.com');
 

Jackie Han

unread,
Aug 9, 2022, 8:46:27 AM8/9/22
to Lofty Shaky, Chromium Extensions, thus...@gmail.com, hrg...@gmail.com
One more note for the new favicon api: It is a warning permission if you don't have other related permission (like browsing history permission).

Screen Shot 2022-08-09 at 20.39.39.png

Juraj M.

unread,
Aug 9, 2022, 8:57:08 AM8/9/22
to Chromium Extensions, Jackie Han, Chromium Extensions, thus...@gmail.com, hrg...@gmail.com, bags...@gmail.com
Thank you Jackie for the warning!
That's probably a showstopper for many existing extensions :(.
How can you tell that having browser history permission won't trigger this? Could `<all_urls>` help as well?

And is there some list of permissions with warnings and relations between them? The existing one is for MV2:
https://developer.chrome.com/docs/extensions/mv2/permission_warnings/#permissions_with_warnings

Also, was the documentation for this API released already? I can't find it.

Jackie Han

unread,
Aug 9, 2022, 9:04:33 AM8/9/22
to Juraj M., Chromium Extensions, thus...@gmail.com, hrg...@gmail.com, bags...@gmail.com
For example, if you already have "history" or "tabs" permission, then "favicon" permission will not show.
You can check whether "Read the icons of the websites you visit" permission in your extension permissions at chrome://extensions/?id=extension_id 

Jackie Han

unread,
Aug 9, 2022, 9:27:06 AM8/9/22
to Juraj M., Chromium Extensions, thus...@gmail.com, hrg...@gmail.com, bags...@gmail.com
I reported a bug for this unnecessary warning

Juraj M.

unread,
Aug 9, 2022, 11:49:55 AM8/9/22
to Chromium Extensions, Jackie Han, Chromium Extensions, thus...@gmail.com, hrg...@gmail.com, bags...@gmail.com, Juraj M.
Thanks a lot Jackie! And great job reporting it!
It seems I'm lucky with my already present "tabs" permission! Hooray :)

Simeon Vincent

unread,
Aug 10, 2022, 2:30:07 PM8/10/22
to Juraj M., Chromium Extensions, Jackie Han, thus...@gmail.com, hrg...@gmail.com, bags...@gmail.com
The new chrome-extension://<EXT_ID>/_favicon/ probably uses the same underlying mechanism of the old chrome://favicon/ API.

FWIW I believe both APIs use Chrome's internal favicon service and their behaviors are closely tied to its implementation.


From a developer's point of view, MV2 chrome://favicon/ is easier to use.

IMO the core problem with the chrome://favicon API is that it blends arguments with URL structure. In order to effectively construct a URL, you need to know some rather esoteric details about the path structure of that URL. The query parameter approach used in the new URL scheme better matches typical HTTP API request patterns and is more directly analogous to a typical function call. 


And is there some list of permissions with warnings and relations between them? The existing one is for MV2:
https://developer.chrome.com/docs/extensions/mv2/permission_warnings/#permissions_with_warnings

Interactions between permissions and their warning messages isn't described in our docs, but enterprising readers can poke through Chromium's source for the implementation details. 


Thanks for calling out that the "favicon" permission warning wasn't listed. I just created and merged pull request to add it to this page. 


Also, was the documentation for this API released already? I can't find it.

Docs for the Favicon API are in progress. I'd link a PR, but we're not at that stage yet. We have an example extension in the chrome-extension-samples repo, but the discussion in this thread already covers everything it does.


I reported a bug for this unnecessary warning.
https://bugs.chromium.org/p/chromium/issues/detail?id=1351379

This warning isn't new or unnecessary. I'll add a comment to that bug to discuss this in more detail.

If you haven't encountered it before, I'd be willing to be that it was likely hidden due to the way Chrome coalesces warnings for multiple permissions. For example, my quick reading of this file has the favicon permission warning "absorbed" by many other permissions including debugger, automation, <all_urls>, history, and so on.


Simeon - @dotproto
Chrome Extensions DevRel


--
You received this message because you are subscribed to the Google Groups "Chromium Extensions" group.
To unsubscribe from this group and stop receiving emails from it, send an email to chromium-extens...@chromium.org.

Juraj M.

unread,
Aug 10, 2022, 3:07:07 PM8/10/22
to Chromium Extensions, Simeon Vincent, Chromium Extensions, Jackie Han, thus...@gmail.com, hrg...@gmail.com, bags...@gmail.com, Juraj M.
You've been busy!
Updated docs, created example repo and wrote all this useful info!
Great job! And super helpful, thank you Simeon :)

hrg...@gmail.com

unread,
Aug 10, 2022, 8:09:27 PM8/10/22
to Chromium Extensions, Simeon Vincent, Chromium Extensions, Jackie Han, thus...@gmail.com, hrg...@gmail.com, bags...@gmail.com, juraj....@gmail.com
 
This warning isn't new or unnecessary. I'll add a comment to that bug to discuss this in more detail.

If you haven't encountered it before, I'd be willing to be that it was likely hidden due to the way Chrome coalesces warnings for multiple permissions.

Indeed, the favicon warning has always been there at least since MV2. This can be tested by running this line of code in the console of an MV2 extension:

chrome.management.getPermissionWarningsByManifest('{"name":"","version":"1","manifest_version":2,"permissions":["chrome://favicon/"]}', console.log)

This line of code can be used as a general technique to know which permissions produce warnings and whether adding a new permission will produce a new warning for existing users.

Jackie Han

unread,
Aug 10, 2022, 8:37:03 PM8/10/22
to hrg...@gmail.com, Chromium Extensions, Simeon Vincent, thus...@gmail.com, bags...@gmail.com, juraj....@gmail.com
I give an incompatible example, see https://bugs.chromium.org/p/chromium/issues/detail?id=1351379#c6

hrg.wea,

Your code "chrome.management.getPermissionWarningsByManifest(...)" can only prove the "present" implementation, not the "past" implementation. You didn't run that code a year ago, right? You only run it at present.

On my browser, I installed my CWS's bookmarks management extension(MV2) last year. At the installation time, I remember it only shows bookmarks warning, no favicon warning. A few days ago, I published a new version that uses MV3 favicon permission, the browser disabled upgrading and showed the new favicon warning(the screenshot in my previous post). This disable behaviour proves that there was no favicon warning in the past.

I tested this extension on the Edge store at present, which is still the old MV2 extension. When I install it, it does show a favicon warning, but when I check edge://extensions/?id=extension_id after installing, there is no favicon warning in permissions. That is weird.

Jackie Han

unread,
Aug 10, 2022, 9:26:35 PM8/10/22
to Simeon Vincent, Juraj M., Chromium Extensions, thus...@gmail.com, hrg...@gmail.com, bags...@gmail.com
IMO the core problem with the chrome://favicon API is that it blends arguments with URL structure. In order to effectively construct a URL, you need to know some rather esoteric details about the path structure of that URL. The query parameter approach used in the new URL scheme better matches typical HTTP API request patterns and is more directly analogous to a typical function call.

I strongly recommend adding a new function to get the favicon URL, similar to chrome.runtime.getURL(path). For example, chrome.runtime.getFaviconURL(url, size, other parameters).

Most of the time, developers don't need to know these details, no matter what it looks like. And when the implementation changes, developers don't need to update their code.

Jackie Han

unread,
Aug 10, 2022, 9:43:32 PM8/10/22
to Simeon Vincent, Juraj M., Chromium Extensions, thus...@gmail.com, hrg...@gmail.com, bags...@gmail.com
Another suggestion for favicon API. Currently, developers don't know whether the browser cached the favicon, if the browser doesn't cache it, it returns a general icon. Developers can't handle it in this case.

I would like to custom this fallback case when the browser doesn't know the favicon.

hrg...@gmail.com

unread,
Aug 10, 2022, 9:51:02 PM8/10/22
to Chromium Extensions, Jackie Han, juraj....@gmail.com, Chromium Extensions, thus...@gmail.com, hrg...@gmail.com, bags...@gmail.com, Simeon Vincent
I usually test things in old Chrome versions too, which I did in this case. The favicon permission warning has existed since at least Chrome 49 (March 2016).
As Simeon mentioned, the reason why the favicon warning may not be present is because another permission with wider access takes precedence (which is not the case of the "bookmarks" permission).

You can check that by running this line in an old Chrome version:
chrome.management.getPermissionWarningsByManifest('{"name":"","version":"1","manifest_version":2,"permissions":["chrome://favicon/", "bookmarks"]}', console.log)

The result is:
['Read the icons of the websites you visit', 'Read and change your bookmarks']

Jackie Han

unread,
Aug 10, 2022, 10:05:43 PM8/10/22
to hrg...@gmail.com, Chromium Extensions, juraj....@gmail.com, thus...@gmail.com, bags...@gmail.com, Simeon Vincent
OK, if you did test it on Chrome 49. Now, the question is why the extension upgrade is disabled from MV2 to MV3? It only has bookmarks  permission and favicon(chrome://favicon) permission.

PS: Chromium is changing its code continually. To prove it's old behavior, you need to use an old version, not the new version. I just want to say that in my previous post.

Jackie Han

unread,
Aug 10, 2022, 10:16:35 PM8/10/22
to Simeon Vincent, Juraj M., Chromium Extensions, thus...@gmail.com, hrg...@gmail.com, bags...@gmail.com
Docs for the Favicon API are in progress. I'd link a PR, but we're not at that stage yet. We have an example extension in the chrome-extension-samples repo, but the discussion in this thread already covers everything it does.

  const url = '_favicon/?page_url=https://www.google.com&size=64';
  img.src = chrome.runtime.getURL(url);


1. The above example code in that repo is not correct.
the "page_url" parameter should be changed to "pageUrl". Because Chrome now uses camelCase params instead of snake_case in JS context. See here.

2. I want to know why you don't escape the parameter value?
In my test on Chrome Canary 106, both pageUrl=https://www.google.com and pageUrl=https%3A%2F%2Fwww.google.com can work.
The former does not follow the URL parameter specification. Is it a bug?



Jackie Han

unread,
Aug 10, 2022, 10:31:11 PM8/10/22
to Simeon Vincent, Juraj M., Chromium Extensions, thus...@gmail.com, hrg...@gmail.com, bags...@gmail.com
Thanks for calling out that the "favicon" permission warning wasn't listed. I just created and merged pull request to add it to this page. 

 Thanks Simeon, I see the document has been updated.

On Thu, Aug 11, 2022 at 2:29 AM Simeon Vincent <sim...@chromium.org> wrote:

hrg...@gmail.com

unread,
Aug 10, 2022, 11:07:12 PM8/10/22
to Chromium Extensions, Jackie Han, Chromium Extensions, juraj....@gmail.com, thus...@gmail.com, bags...@gmail.com, Simeon Vincent, hrg...@gmail.com
Now, the question is why the extension upgrade is disabled from MV2 to MV3? It only has bookmarks  permission and favicon(chrome://favicon) permission.

That sounds like a bug to me. Upgrading from MV2 to MV3 with the same permissions should not disable the extension.
The issue is most likely that they are not taking into account that the "favicon" permission in MV3 is the same as "chrome://favicon/" in MV2. So, Chrome thinks there's a new permission when in fact there isn't.
 
Message has been deleted
Message has been deleted

Uladzimir Yankovich

unread,
Aug 11, 2022, 10:22:22 AM8/11/22
to Chromium Extensions, hrg...@gmail.com, Jackie Han, Chromium Extensions, juraj....@gmail.com, thus...@gmail.com, bags...@gmail.com, Simeon Vincent
I just tested the new API. God, it makes me want to cry.

1. Not all icons are returned by the API. Here is an example - https://share.cleanshot.com/mc99bD. The icon is in the tab, the icon is in the bookmark, but the API didn't return anything.

2. Colleagues, why do we need size parameter, if all the same if we have a lot of high resolution icons, you still suggest us to use blurred 32x32 .ico? https://share.cleanshot.com/yTAv8A

Give us a full-fledged API, please!

Uladzimir Yankovich

unread,
Aug 11, 2022, 10:34:37 AM8/11/22
to Chromium Extensions, Uladzimir Yankovich, hrg...@gmail.com, Jackie Han, Chromium Extensions, juraj....@gmail.com, thus...@gmail.com, bags...@gmail.com, Simeon Vincent
I suggest that everyone vote for this ticket — https://bugs.chromium.org/p/chromium/issues/detail?id=1350713 
Reply all
Reply to author
Forward
0 new messages