Your chrome extension needs two sets of icons
Having only one set of icons for your extension, doesn't provide the best user experience. Do you know that you can change the icon of your extensions dynamically?
Usual setup
Usually when developers build their extensions, they have 1 set of extension icons in multiple sizes. This is good. But if your extension doesn't work on all sites, then this doesn't provide the best user experience. Also know that chrome extensions don't work on the following urls.
A visual cue to the user on whether the extension can be used on a particular site goes a long way in ensuring good user experience.
Even if your extension works on all sites, it's better to have other set of icons as extensions are not supported on some sites (A few are listed above).
{
"icons": {
"16": "images/icon_16.png",
"48": "images/icon_48.png",
"128": "images/icon_128.png"
}
}
You can define the default icons as usual in the manifest.json
file as shown above. Though you can set both the active & inactive
icons dynamically, you will have to define one set of icons in the manifest.json
file. This is required by the Chrome web store.
Dynamically setting the extension icons
To achieve this, you need to have a background script. If you don't have one already, create one and add it to the manifest.json
.
Have 2 sets of icons ready, before we proceed. One for active and other for inactive state. Create 2 objects in the background script with the icons.
Here's how it will look. The path has to be relative from the extension
directory.
const supportedIcon = {
16: 'images/icon_16.png',
48: 'images/icon_48.png',
128: 'images/icon_128.png'
};
const unsupportedIcon = {
16: 'images/icon-dark_16.png',
48: 'images/icon-dark_48.png',
128: 'images/icon-dark_128.png'
};
Here images
directory is present in the extension
directory. This is the parent directory that has the extension code
and the manifest.json
file.
Code to dynamically set the icon. Add this to the background script.
function isUrlSupported(url) {
if (url.startsWith('https://chrome.google.com/') || url.startsWith('https://chromewebstore.google.com') || url.startsWith('brave://')) {
return false;
}
const matches = chrome.runtime.getManifest().content_scripts[0].matches;
return matches.some(match => {
const regex = new RegExp('^' + match.replace(/\*/g, '.*') + '$');
return regex.test(url);
});
}
// Listen for tab updates
chrome.tabs.onUpdated.addListener((tabId, changeInfo, tab) => {
if (changeInfo.status === 'complete') {
if (isUrlSupported(tab.url)) {
chrome.action.setIcon({
path: supportedIcon,
tabId: tabId
});
} else {
chrome.action.setIcon({
path: unsupportedIcon,
tabId: tabId
});
}
}
});
In the above code, I am fetching the matches value from content_scripts
in the manifest.json
and updating the icons
accordingly. So the sites to which I inject the content_scripts I show the supported icons and for others I show the
unsupported set of icons.
You can update the logic in the function isUrlSupported
. In the example above, I am checking the matches value in content_scripts.
You can check other values depending on your extension. One example is to check the values from host_permissions
array.
Conclusion
Having 2 sets of icons is not mandatory, but improves the user experience greatly. Go ahead and update your extensions to support this.