# Errors using webextension-polyfill to make a cross-browser add-on

**URL:** https://discourse.mozilla.org/t/errors-using-webextension-polyfill-to-make-a-cross-browser-add-on/102342
**Category:** Development
**Created:** [August 8, 2022, 12:25pm UTC](https://discourse.mozilla.org/t/errors-using-webextension-polyfill-to-make-a-cross-browser-add-on/102342 "2022-08-08T12:25:35Z")
**Posts on this page:** 13
**Page:** 1

<div class="post-metadata">

### Author: ![adamouization](https://sea1.discourse-cdn.com/flex001/user_avatar/discourse.mozilla.org/adamouization/32/58548_2.png) [@adamouization](https://discourse.mozilla.org/u/adamouization)
#### Post date: [August 8, 2022, 12:25pm UTC](https://discourse.mozilla.org/t/errors-using-webextension-polyfill-to-make-a-cross-browser-add-on/102342/1 "2022-08-08T12:25:35Z")

</div>

Hi everyone,

I have been attempting to improve my add-on by making it cross-browser so that it’ll work on Google Chrome.

My add-on is a simple pop-up that modifies JS on the webpage that it is opened on via content scripts. Here my file structure to have an idea of the different scripts being used (I developed my add-on for Firefox, so it works as expected on this browser):

 ![Screenshot 2022-08-08 at 14.17.35](https://us1.discourse-cdn.com/flex001/uploads/mozilla/original/3X/5/5/55233c758f5ebfbc9053e91d200733ee13056fb7.png)

After looking for relevant documentation to make it cross-browser, I found the following two links:

- [Building a cross-browser extension](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Build_a_cross_browser_extension)

- [WebExtension browser API Polyfill](https://github.com/mozilla/webextension-polyfill/)

I have tried implementing what is described on the documentation by installing `browser-polyfill` via npm, and using it like by adding those lines in my `manifest.json`:

```
"background": {
    "scripts": [
      "node_modules/webextension-polyfill/dist/browser-polyfill.js"
    ]
  }

```

I also tried using this line at the top of my `popup_listener.js` file but it was not successful:

```
browser.tabs.executeScript({file: "browser-polyfill.js"});

```

Currently, the extension loads with no errors on Chrome, and when opening the add-on on the toolbar the UI loads correctly as well. However the following error occurs when using the functionality of the add-on:

```
Uncaught ReferenceError: browser is not defined

```

Here is the full stack trace on Chrome:

 ![Screenshot 2022-08-08 at 14.23.21](https://us1.discourse-cdn.com/flex001/uploads/mozilla/original/3X/2/0/20899f429d1f01669adf60b9d6e5ab491296d172.png)

I am sure I am missing something from the documentation but I cannot find anything that is helpful. Any help from anyone who managed to make a cross-browser add-on would be appreciated.

Thanks for your help 🙂

---

<div class="post-metadata">

### Author: ![juraj.masiar](https://sea1.discourse-cdn.com/flex001/user_avatar/discourse.mozilla.org/juraj.masiar/32/30587_2.png) [@juraj.masiar](https://discourse.mozilla.org/u/juraj.masiar)
#### Post date: [August 8, 2022, 3:57pm UTC](https://discourse.mozilla.org/t/errors-using-webextension-polyfill-to-make-a-cross-browser-add-on/102342/2 "2022-08-08T15:57:01Z")

</div>

The browser polyfill library is super simple code.  
You could say, that all it does is run a script with code like: `window.browser = {...}`

Now that you know how it works, you should know how to use it.  
All you need to do is MAKE SURE the library code is executed BEFORE your code.

By your code I mean in [all contexts](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/Anatomy_of_a_WebExtension) of your addon.  
So add it in your background script array in manifest, add it in the popup.html page as a script tag above your own script tags. And if you are injecting JS into current page, inject the library before that.

And that should be it 🙂.

I’m not sure though how do you bundle it though when it’s in the “node\_modules” folder. Are you using webpack or some other bundler? If not, then just download it or copy it from there into some “library” folder in your source folder.

---

<div class="post-metadata">

### Author: ![adamouization](https://sea1.discourse-cdn.com/flex001/user_avatar/discourse.mozilla.org/adamouization/32/58548_2.png) [@adamouization](https://discourse.mozilla.org/u/adamouization)
#### Post date: [August 8, 2022, 10:14pm UTC](https://discourse.mozilla.org/t/errors-using-webextension-polyfill-to-make-a-cross-browser-add-on/102342/3 "2022-08-08T22:14:02Z")

</div>

Hi Juraj,

Thanks for the quick and helpful reply!

What you said makes sense, I have made sure that the library is being used in every location before a reference to `browser.`. However, I am still having trouble getting it to work properly as I am getting the same error on Chrome.

I have imported the library in the `manifest.json` using

```
"background": {
    "scripts": [
      "node_modules/webextension-polyfill/dist/browser-polyfill.js"
    ]
  },

  "content_scripts": [{
    "js": [
      "node_modules/webextension-polyfill/dist/browser-polyfill.js",
      "content_scripts/create_total_cards_button.js",
      "content_scripts/hide_card_counters.js",
      "content_scripts/show_card_counters.js"
    ]
  }]

```

And I have references the library before my popup listener by adding the script first:

```
<script type="application/javascript" src="node_modules/webextension-polyfill/dist/browser-polyfill.js"></script>
<script type="application/javascript" src="popup_listener.js"></script>

```

However this still does not seem to be working and `browser.tabs` is not being recognised. Did you ever run into an issue like this that required additional steps?

Thanks for the help, I appreciate it!

PS: checked out your website and add-ons, they’re really cool and look amazing! 🙂

---

<div class="post-metadata">

### Author: ![Adam](https://avatars.discourse-cdn.com/v4/letter/a/4af34b/32.png) [@Adam](https://discourse.mozilla.org/u/Adam)
#### Post date: [August 9, 2022, 2:23am UTC](https://discourse.mozilla.org/t/errors-using-webextension-polyfill-to-make-a-cross-browser-add-on/102342/4 "2022-08-09T02:23:51Z")

</div>

I’m pretty sure I got the same error, but it was over a year ago and I don’t remember too well ☹ I think it didn’t work for me when I copied the file directly from the github page ( [https://github.com/mozilla/webextension-polyfill/blob/master/src/browser-polyfill.js](https://github.com/mozilla/webextension-polyfill/blob/master/src/browser-polyfill.js) ).

I use this file and I don’t have any problems:  
[https://unpkg.com/browse/webextension-polyfill@0.9.0/dist/browser-polyfill.js](https://unpkg.com/browse/webextension-polyfill@0.9.0/dist/browser-polyfill.js)

---

<div class="post-metadata">

### Author: ![juraj.masiar](https://sea1.discourse-cdn.com/flex001/user_avatar/discourse.mozilla.org/juraj.masiar/32/30587_2.png) [@juraj.masiar](https://discourse.mozilla.org/u/juraj.masiar)
#### Post date: [August 9, 2022, 7:00am UTC](https://discourse.mozilla.org/t/errors-using-webextension-polyfill-to-make-a-cross-browser-add-on/102342/5 "2022-08-09T07:00:35Z")

</div>

I think I see the problem, you are using wrong “src” path (relative). There is no “node\_moudles” in the “popup” folder, there is only your javascript.

So to target “node\_modules” you need to either go one folder up, like “`../node_modules/...`” or even better, use slash to make it absolute, like this: “/node\_modules/…”.

This applies to all imports and all file access. If you are in the nested folder and you type name of the file, it will look for the file in the current folder. So it’s best to use full path from the root folder, that can be done by adding “/” prefix and then full path to the target file.

But just in case, let’s make it simple, don’t use it from node\_modules directory but download it from their repo directly (like Adam said), see their releases page:

> **[Releases · mozilla/webextension-polyfill](https://github.com/mozilla/webextension-polyfill/releases)**
>
> A lightweight polyfill library for Promise-based WebExtension APIs in Chrome - mozilla/webextension-polyfill

_(you can use “Ctrl+s” on [this page](https://unpkg.com/webextension-polyfill@0.9.0/dist/browser-polyfill.min.js))_

Download the file and place it to the root folder. Then when you use it, use “/browser-polyfill.min.js” as path.

---

<div class="post-metadata">

### Author: ![adamouization](https://sea1.discourse-cdn.com/flex001/user_avatar/discourse.mozilla.org/adamouization/32/58548_2.png) [@adamouization](https://discourse.mozilla.org/u/adamouization)
#### Post date: [August 10, 2022, 5:27pm UTC](https://discourse.mozilla.org/t/errors-using-webextension-polyfill-to-make-a-cross-browser-add-on/102342/6 "2022-08-10T17:27:08Z")

</div>

Hi,

Thanks for the help Juraj and Adam.

Unfortunately I am yet to get my add-on to work on Chrome despite your help!

I have tried the following:

- Installed both the `browser-polyfill.js` and `browser-polyfill.min.js` libraries manually in my root directory.
- Referenced the library directly using the root path as you guys recommended `/browser-polyfill.js` in the following locations:
  - My manifest.json using `"background": {"scripts": ["browser-polyfill.js"]},`
  - My main popup HTML document before the popup\_listener.js is called using `<script src="/browser-polyfill.js"></script>`

It seems to be loading correctly now but I am getting a mountain of errors that seem to be originating from the browser-polyfill library, and consequently errors in my JS code saying `"Uncaught ReferenceError: browser is not defined"`.

Here are some of the errors that I am facing on Chrome when loading the add-on and using it for the first time:

 ![Screenshot 2022-08-10 at 19.24.52](https://us1.discourse-cdn.com/flex001/uploads/mozilla/original/3X/a/0/a07234dfd734a275ba135b24610886b0213d74b5.png)

If it helps clarify what I am doing, I have pushed my code to a [GitHub branch](https://github.com/Trello-Card-Counter/Trello-Card-Counter-Mozilla-Extension/tree/3-new-make-extension-cross-browser-compatible-1).

I am curious, has this happened to any of you guys? Am I missing something fundamental? Perhaps I am supposed to add some code myself once I’ve loaded this library to make sure `browser` is recognised by Chrome? Is there maybe a better way to do this? Maybe just create a separate extension for Chrome directly?

Anyway, thanks again for the help, I appreciate it!

---

<div class="post-metadata">

### Author: ![juraj.masiar](https://sea1.discourse-cdn.com/flex001/user_avatar/discourse.mozilla.org/juraj.masiar/32/30587_2.png) [@juraj.masiar](https://discourse.mozilla.org/u/juraj.masiar)
#### Post date: [August 10, 2022, 5:53pm UTC](https://discourse.mozilla.org/t/errors-using-webextension-polyfill-to-make-a-cross-browser-add-on/102342/7 "2022-08-10T17:53:48Z")

</div>

You have downloaded the wrong file 😃.

In the screenshot source code you see:

```auto
  // The build process adds a UMD wrapper around this file, which makes the
  // `module` variable available.

```

And then error saying “module” not found.  
The file you have is a source file, it needs to be build first.

Use the `browser-polyfill.min.js ` file instead, that’s already build and minified so it’s small. You won’t really need to debug it anyway 🙂.

**EDIT:**  
But I agree it’s way too complicated even for my taste.  
Not only they don’t have a “dist” folder in their sources (which may be understandable), but even the “releases” page doesn’t have the dist package included. Instead they are hosted on some totally random looking domain `unpkg.com`.

It’s still better than it was before when you had to BUILD IT YOURSELF! 😃 And it was [not even working on Windows](https://github.com/mozilla/webextension-polyfill/issues/101) 😃.

---

<div class="post-metadata">

### Author: ![adamouization](https://sea1.discourse-cdn.com/flex001/user_avatar/discourse.mozilla.org/adamouization/32/58548_2.png) [@adamouization](https://discourse.mozilla.org/u/adamouization)
#### Post date: [August 10, 2022, 6:11pm UTC](https://discourse.mozilla.org/t/errors-using-webextension-polyfill-to-make-a-cross-browser-add-on/102342/8 "2022-08-10T18:11:46Z")

</div>

I did indeed download the wrong file, my bad. Thanks for spotting it!

I’ve downloaded the correct file now and am using the minified version correctly.

However, I am still getting the `Uncaught ReferenceError: browser is not defined` errors on this line: `browser.tabs.executeScript({file: "../content_scripts/show_card_counters.js"});`

I might be a bit confused about how to use this extension, but it was my understanding that using this library would allow Chrome to recognise `browser` instead of creating a new add-on that uses `chrome`?

Am I missing something obvious?

PS: that sounds dreadful, but yeah the documentation and releases can definitely be improved 😃

---

<div class="post-metadata">

### Author: ![juraj.masiar](https://sea1.discourse-cdn.com/flex001/user_avatar/discourse.mozilla.org/juraj.masiar/32/30587_2.png) [@juraj.masiar](https://discourse.mozilla.org/u/juraj.masiar)
#### Post date: [August 10, 2022, 6:42pm UTC](https://discourse.mozilla.org/t/errors-using-webextension-polyfill-to-make-a-cross-browser-add-on/102342/9 "2022-08-10T18:42:54Z")

</div>

Don’t worry, we can fix this easily.  
You are obviously not injecting the polyfill with your content scripts.

For example:

```auto
window.onload = (event) => { // https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event
  browser.tabs.executeScript({file: "../content_scripts/create_total_cards_button.js"});
};

```

You can change it into something like this:

```auto
window.onload = async event => { // https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event
  await browser.tabs.executeScript({file: "/browser-polyfill.min.js"});
  await browser.tabs.executeScript({file: "/content_scripts/create_total_cards_button.js"});
};

```

Note that I made it async so that I can await the polyfill injection.

Also, regarding the script injection, use the “/” in the beginning, it’s also mentioned in the docs:

 ![image](https://us1.discourse-cdn.com/flex001/uploads/mozilla/original/3X/7/8/78a23db7ab29dc00c5871e6c7cb93046c816b6aa.png)

[tabs.executeScript() - Mozilla | MDN](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/tabs/executeScript#file)

---

<div class="post-metadata">

### Author: ![juraj.masiar](https://sea1.discourse-cdn.com/flex001/user_avatar/discourse.mozilla.org/juraj.masiar/32/30587_2.png) [@juraj.masiar](https://discourse.mozilla.org/u/juraj.masiar)
#### Post date: [August 10, 2022, 6:51pm UTC](https://discourse.mozilla.org/t/errors-using-webextension-polyfill-to-make-a-cross-browser-add-on/102342/10 "2022-08-10T18:51:17Z")

</div>

Also few more things to mention after looking at your github page:

- you can use [ko-fi.com](http://ko-fi.com) for donations, it has no fees and it’s full of features
- in your manifest file:

```auto
  "background": {
    "scripts": ["browser-polyfill.min.js"]
  },

```

You can remove it completely since you don’t have any background scripts to be polyfilled 🙂.

- your content scripts are in a wrong order, I’m pretty sure they are executed in the defined order, so you need to make the polyfill first!

```auto
  "content_scripts": [{
    "matches" : ["<all_urls>"],
    "js": [
      "content_scripts/create_total_cards_button.js",
      "content_scripts/hide_card_counters.js",
      "content_scripts/show_card_counters.js",
      "browser-polyfill.min.js" // this is bad, it needs to be first
    ]
  }],

```

Also, you do you really need to inject all those scripts into all pages? Isn’t this extension for some specific site only?

---

<div class="post-metadata">

### Author: ![adamouization](https://sea1.discourse-cdn.com/flex001/user_avatar/discourse.mozilla.org/adamouization/32/58548_2.png) [@adamouization](https://discourse.mozilla.org/u/adamouization)
#### Post date: [August 11, 2022, 2:05pm UTC](https://discourse.mozilla.org/t/errors-using-webextension-polyfill-to-make-a-cross-browser-add-on/102342/11 "2022-08-11T14:05:22Z")

</div>

Wow , thanks for all the help not just with this question but with my whole extension in general. You’re very knowledgeable about browser extensions, very impressive!

So I’ve implemented your recommendations again and it is partially working. I re-ordered the content script to have `browser-polyfill` be first, turned the `window.onload` event into an `async` one and used `await` like you recommended.

However, I am unsure how to use for the the next content script to execute and the ones inside an event listener. Do I basically wrap my whole code in `popup_listener.js` into an `async event`? Or do I create multiple `async events`? I am currently getting more errors linked to polyfill library when using this code, which is weird because I am definitely using it correctly now as it works for the first 2 `executeScript()` but not the first one:

```
window.onload = async () => { // https://developer.mozilla.org/en-US/docs/Web/API/Window/load_event
    await browser.tabs.executeScript({file: "/browser-polyfill.min.js"});
    await browser.tabs.executeScript({file: "/content_scripts/create_total_cards_button.js"});
    await browser.tabs.executeScript({file: "../content_scripts/show_card_counters.js"}); // this does not run
};

// Listen for events on the on/off toggle switch button to decide which script to run.
document.addEventListener("click", (e) => {

    // Show the number of Trello card in each column.
    if (e.target.checked === true) {
        browser.tabs.executeScript({file: "../content_scripts/show_card_counters.js"});
    }

    // Hide the number of Trello card in each column.
    if (e.target.checked === false) {
        browser.tabs.executeScript({file: "../content_scripts/hide_card_counters.js"});
    }

});

```

 ![Screenshot 2022-08-11 at 16.03.21](https://us1.discourse-cdn.com/flex001/uploads/mozilla/original/3X/5/f/5f1a1a915e792f5659badc21fefb9a70937bc04b.png)

Additionally I addresses some of your recommendations (most of them came while I was trying to get my extension to work on Chrome so I’ve been trying so many different things I found online :D):

- added `"/"` at the beginning like you said
- removed polyfill being used in background scripts as I don’t have any
- modified the`"matches"` key to only relevant pages.

PS: I’ve been using “Buy Me A Coffee” but they take fees, so thanks for sharing ko-fi with me! 🙂

---

<div class="post-metadata">

### Author: ![juraj.masiar](https://sea1.discourse-cdn.com/flex001/user_avatar/discourse.mozilla.org/juraj.masiar/32/30587_2.png) [@juraj.masiar](https://discourse.mozilla.org/u/juraj.masiar)
#### Post date: [August 12, 2022, 1:23pm UTC](https://discourse.mozilla.org/t/errors-using-webextension-polyfill-to-make-a-cross-browser-add-on/102342/12 "2022-08-12T13:23:15Z")

</div>

So, in your code you still use wrong path: `executeScript({file: "../content_scripts`

Don’t use `..`, always start with “/”.

Also, I’ve just noticed, you are using old API that’s gonna disappear in 4 months in Chrome 🙂.  
Did you hear about [Manifest V3](https://developer.chrome.com/docs/extensions/mv3/intro/)? You need to migrate your chrome extension into MV3 till January 2023.

The good news is, the new API supports injecting multiple files, for example:

```auto
await browser.scripting.executeScript({
  target: {
    tabId: tabId, 
    allFrames: false,
  }, 
  files: [
    '/browser-polyfill.min.js', 
    '/content_scripts/foobar.js',
  ],
});

```

More info:

> **[scripting.executeScript() - Mozilla | MDN](https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/scripting/executeScript)**
>
> Injects a script into a target context. The script is run at document\_idle by default.

---

<div class="post-metadata">

### Author: ![adamouization](https://sea1.discourse-cdn.com/flex001/user_avatar/discourse.mozilla.org/adamouization/32/58548_2.png) [@adamouization](https://discourse.mozilla.org/u/adamouization)
#### Post date: [August 13, 2022, 9:39am UTC](https://discourse.mozilla.org/t/errors-using-webextension-polyfill-to-make-a-cross-browser-add-on/102342/13 "2022-08-13T09:39:33Z")

</div>

That did it, it’s working perfectly on Chrome now! 🙂

Didn’t even had to change the event listener, just a combination of all the tips you shared and using root paths. Thanks a lot for the help!

I’ll definitely try to update it to use manifest V3 next, might need your help again, I had a look at the documentation and there isn’t much info shared there as well 😆

Thanks again for the help!
