Open background page

I am doing some experiments in order to understand background pages and extension pages.

My aim is to open the “only” background page of an extension and display it in the browser.

So in the manifest.json I have:

"background": {
   "page": "index.html"

and as soon as the extension is loaded, I find in console that index.html is properly loaded, even if it is not displayed in any tab.

Problems arise when I try to open index.html in a tab: included scripts are executed again, a fresh new scope is created for the index.html page, while I expect the background page scope to be unique.

For example, if index.html includes a script

<script src="/js/background.js" type="module"></script>

and this script adds a browser.browserAction.onClicked listener

browser.browserAction.onClicked.addListener(async (tab, onClickData)=>{
    try {
        await browser.tabs.create({url: '/index.html'});
    } catch (e) {

that listener is added every time index.html is opened, and a single click event causes the execution of multiple listeners.

Another example, if I want to keep a variable in background scope, this variable gets redefined every time index.html is opened in a tab.

What I understand from this behavior is that opening a page from background is the same as opening an “Extension Page”: am I right ?

Hence my question is:

  • a background page is meant to be opened and displayed in a tab ?
  • what is the correct way to do it ?

I don’t think the background page is meant to be displayed… at least I haven’t seen anyone doing it.

The correct way would be to have a normal page for the UI, which sends messages to the background script (and the background page can send something to the UI page as well if needed).