Dark theme_icons are ignored in Manifest v3 extension

As part of porting my Table of contents extension to Firefox, I’d like to make sure its (monochrome) icon is legible in both light and dark modes.

As described on the MDN page for the action key, I tried specifying light and dark variants for the theme_icons:


    "action": {
        "default_popup": "popup.html",
        "default_icon": {
            "16": "images/toolbar-icon-light-16.png",
            "19": "images/toolbar-icon-light-19.png",
            […]
        },
		"theme_icons": [
			{
				"light": "images/toolbar-icon-light-16.png",
				"dark": "images/toolbar-icon-dark-16.png",
				"size": 16
			},
			{
				"light": "images/toolbar-icon-light-19.png",
				"dark": "images/toolbar-icon-dark-19.png",
				"size": 19
			},
			[…]

But, Firefox seems to ignore the dark key: even when I switch my OS to dark mode, and Firefox automatically adapts its theme, the light theme version of the icon still gets used:

(to make sure, I tried changing the URL specified in the light key of the theme_icons, and sure enough, that’s the one Firefox is displaying; both in light and dark mode)

This was tried in Firefox 112 on macOS 13.3.1, and in Firefox 112 on Windows 10 19044.2846.
I also first reproduced this issue a few months ago, mid-January, in the Firefox version that was current at the time.

I found some other topics here about the issue, but I can’t see differences between the code they end up successfully using, and mine. Does anyone know what I’m doing wrong?

You can see the full manifest on GitHub.
If you kindly want to reproduce the bug firsthand, you can clone the repo then load the Shared (Extension)/Resources/ folder as an extension.

Did this work for you in a mv2 extension?

If so, please file a bug with a link and STR.

I’ve never written a Manifest v2 extension, so I can’t say.

These two threads seem to have similar code working in v2, though:

I haven’t been able to find a v3 extension with dark/light icon variants, yet—have you run into any working sample?

Of note, I can actually reproduce the issue in Chrome (version 109), suggesting there is something wrong with my manifest.
(and in Safari, for which the extension was originally developed, the image is in my case treated as a mask anyway, so the light/dark variants don’t matter)

I’m finding this nonfunctional for me too with Manifest V3 on Firefox.
I’ve verified that theme_icons does in fact work in V2, see the example extension: https://github.com/mdn/webextensions-examples/tree/main/beastify
I can change to dark mode theme, and the beastify icon changes but my Manifest V3 icon does not.

It seems there’s chatter in Chrome by developers saying there’s no way to change their icon. theme_icons isn’t even mentioned in this bug report, but it seems like all acknowledge there’s currently no way to change icons in Chrome:
https://issues.chromium.org/issues/41419485

super frustrating!

Does anyone have a JS code workaround where my background script can detect dark or light themes and update the icon itself? Preferably without polling?

I don’t have enough time to give this as much thought as I’d like, but the first idea that came to mind is to use matchMedia in an event page to detect changes.

Haven’t tested this, but something like this should work.

background.js

const lightTheme = window.matchMedia("(prefers-color-scheme: light)");

function setThemeIcon(light) {
  const theme = light ? "light" : "dark";
  return browser.action.setIcon({
    imageData: {
      16: `icons/icon-${theme}-16.png`,
      32: `icons/icon-${theme}-32.png`,
    }
  });
}

// Set initial icon color
setThemeIcon(lightTheme.matches);

// React to theme color changes
lightTheme.onchange((event) => setThemeIcon(event.matches));

Thanks. I thought about doing something with matchMedia, but I’m wondering if that is monitoring the browser theme dark/light or only the contents of the window (i.e. the html page)?

My action button lives in the browser UI itself, so I’m really interested in the browser theme, and wasn’t sure if watchMedia monitored that.

I figured out at least my issue.

I assumed that “light” in theme_icons would be the icon to use for a light theme.
THIS IS NOT THE CASE! :face_with_monocle:
“light” is for themes that are dark
“dark” is for themes that are light
So I guess you’re specifying an icon with “dark” lines or “light” lines

From the docs (action - Mozilla | MDN):

“dark”

A URL pointing to an icon. This icon displays when a theme using dark text is active (such as the Firefox Light theme, and the Default theme if no default_icon is specified).

“light”

A URL pointing to an icon. This icon displays when a theme using light text is active (such as the Firefox Dark theme).

:slightly_smiling_face: Looks like @Cykelero found the same answer, his manifest shows swapping of dark/light images for the “dark” and “light” sections of theme_icons in the git history.

Yes! I was also initially confused by this.

Even with the swap, though, the light/dark switch wasn’t working back at the beginning of 2023, and was fixed in Firefox shortly after, IIRC.