This is a common problem: you’re using a non-persistent background script (e.g. a service worker in ManifestV3) and a chrome.runtime.onInstalled
listener where you register some other listeners.
This is wrong because the onInstalled
event is triggered only on installs/updates for a published extension and it happens asynchronously, which is a problem because chrome
API listeners must be registered synchronously when using a non-persistent background script, otherwise the event that woke the background script won’t be dispatched to this listener i.e. the event will be lost.
It worked for you in developer mode only because reloading an extension is treated by Chrome as an update event reported in onInstalled
. Or maybe you had devtools open for your background script which prevented it from unloading automatically.
Solution
Move the nested addListener
registration outside of chrome.runtime.onInstalled
:
chrome.runtime.onInstalled.addListener(function(info) {
// code that should run on install/update
// ...............
});
chrome.browserAction.onClicked.addListener(function(tab) {
// code that should run on clicking the extension icon
// ...............
});