How to disable (gray out) page action for Chrome extension?

This is a bug in Chrome and so far it’s unclear if it’s even fixable.

Meanwhile, you can maintain the icon yourself:

  1. make a grayscale version of the icon(s) in any image editor and save them separately.

  2. specify the gray icon in manifest.json:

    • ManifestV2:

      "page_action": {
        "default_icon": { "16": "icons/16-gray.png", "32": "icons/32-gray.png" }
      }
      
    • ManifestV3 uses action instead of page_action

      "action": {
        "default_icon": { "16": "icons/16-gray.png", "32": "icons/32-gray.png" }
      }
      
  3. set the normal icon using SetIcon action:

    chrome.declarativeContent.onPageChanged.removeRules(async () => {
      chrome.declarativeContent.onPageChanged.addRules([{
        conditions: [
          new chrome.declarativeContent.PageStateMatcher({
            pageUrl: { hostPrefix: 'docs.google.' },
          }),
        ],
        actions: [
          new chrome.declarativeContent.SetIcon({
            imageData: {
              16: await loadImageData('icons/16.png'),
              32: await loadImageData('icons/32.png'),
            },
          }),
          chrome.declarativeContent.ShowAction
            ? new chrome.declarativeContent.ShowAction()
            : new chrome.declarativeContent.ShowPageAction(),
        ],
      }]);
    });
    
    // SVG icons aren't supported yet
    async function loadImageData(url) {
      const img = await createImageBitmap(await (await fetch(url)).blob());
      const {width: w, height: h} = img;
      const canvas = new OffscreenCanvas(w, h);
      const ctx = canvas.getContext('2d');
      ctx.drawImage(img, 0, 0, w, h);
      return ctx.getImageData(0, 0, w, h);
    }
    

Leave a Comment