I've been stuck on this for a few days. We are upgrading our chrome extension to manifest v3 and getting some unwanted behavior, presumably due to using a service worker. Hoping for some help.
We don't use the standard "popup". Instead, we open a new window (of type "popup") upon the user clicking the browser's icon. This works great, except, when the icon is clicked more than once without closing the other newly created windows, we get a sort of exponential number of windows created. For example, the first time, we get one window created (as expected). The second time, we get two windows created (for a total of 3), etc.
Background.js (our service worker)
chrome.action.onClicked.addListener((tab) => {
chrome.windows.create({
url: chrome.runtime.getURL(`index.html? currentTabId=${tab.id}`), type: 'popup'
})
})
App.js , which we load into our newly created window from Background.js
const port = chrome.runtime.connect(chrome.runtime.id)
port.onMessage.addListener(onMessageListener) // etc etc
We tried this in Background.js (saw it mentioned somewhere 🤷🏼♀️)
chrome.action.onClicked.removeListener(handler)
chrome.action.onClicked.addListener(handler)
We tried checking to see if we already had a window open before registering the listener:
async function getOpenWindow() {
const openPopupWindows = await chrome.windows.getAll({
populate: true,
windowTypes: ['popup'],
})
return openPopupWindows.find((openWindow) =>
openWindow.tabs?.some((tab) => tab.url?.includes(chrome.runtime.id))
)
}
getOpenWindow().then((openWindow) => {
if (!openWindow) {
chrome.action.onClicked.addListener(actionOnClickedListener)
}
})
This seemed to be promising, but when the service worker is inactive, clicking on the icon doesn't open the window on the first try, but does on the second try (not ideal).
Obviously it seems like we are adding more chrome.action.onClicked listeners each time we open the extension. But how can we prevent this?
Any suggestions would be great 🙏🏼 We just want a single window to open up each time the icon is clicked.
Thanks in advance!