Published extension doesn’t work with chrome API listeners inside onInstalled

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
  // ...............
});

Leave a Comment