Content scripts declaration in manifest v3

12,037 views
Skip to first unread message

Cyrille

unread,
Mar 4, 2021, 8:53:08 AM3/4/21
to Chromium Extensions
Hello,

My Chrome extension manifest is currently as follows: I'm trying to make JQuery library accessible from background.js so I have added it as a content script declaration and within the web_accessible_resources as well. Unfortunately, I still get an $ undefined error message when trying to execute a function defined in background.js and relying on JQuery. Any help or clarification would be greatly appreciated:

--------------------------------------------------------------------------
I{
"name": "MyApp",
"description": "My app description",
"version": "1.0",
"manifest_version": 3,
"options_ui": {
    "page": "options.html",
    "open_in_tab": false
},
  
"background": {
    "service_worker": "background.js"
},
  
"content_scripts": [{
    "matches": [ "http://*/*", "https://*/*"],
    "js": ["lib/jquery.min.3.5.1.js"]
}],
       
"web_accessible_resources": [{
 "resources": ["lib/jquery.min.3.5.1.js"],
 "matches": [],
 "extension_ids": []
}],
      
"permissions": ["storage", "activeTab", "scripting", "tabs", "alarms", "notifications"],

"host_permissions": ["http://localhost/*", "*://*/*"],

 "action": {

"default_popup": "popup.html",

"default_icon": {
"16": "images/offline16.png",
"32": "images/offline32.png",
"48": "images/offline48.png",
"128": "images/offline128.png"
}
},
"icons": {
    "16": "images/online16.png",
    "32": "images/online32.png",
    "48": "images/online48.png",
    "128": "images/online128.png"
  }
}
--------------------------------------------------------------------------

Best,

Cyrille

ilyaigpetrov

unread,
Mar 4, 2021, 9:22:46 AM3/4/21
to Chromium Extensions, cyrille....@gmail.com
Hi, Cyrille.

I'm not an expert in MV3 but maybe my notes may help you.

1) Content scripts are not executed within background.js but are executed on web pages in an isolated context (see https://developer.chrome.com/docs/extensions/mv2/content_scripts/#isolated_world). That's why your jquery inside content-scripts affects only web pages (isolated context of a web page, not the same context where web page's non-injected scripts are executed) and not background.

2) You are trying to use service_worker. Service workers are suspended (closed, killed) if they are not used within some period of time. It means you have to inject jquery into background every time service worker is awoken or launched.

3) You have to inject jquery into your service worker. And this may be tough or even impossible without something that converts your jquery to a version which works inside a service worker (e.g., see https://stackoverflow.com/a/33944817/521957).

Please, take my words with a grain of salt because I'm not an expert in MV3.

Best regards,
Ilya.

ilyaigpetrov

unread,
Mar 4, 2021, 9:37:27 AM3/4/21
to Chromium Extensions, cyrille....@gmail.com
Maybe you just don't need jquery in your service worker but instead you need it inside a content-script.

--
You received this message because you are subscribed to a topic in the Google Groups "Chromium Extensions" group.
To unsubscribe from this topic, visit https://groups.google.com/a/chromium.org/d/topic/chromium-extensions/xGrSA9iFpIc/unsubscribe.
To unsubscribe from this group and all its topics, send an email to chromium-extens...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/chromium-extensions/b0e01b94-cf12-4599-b5eb-b98a3fd69435n%40chromium.org.

Cyrille

unread,
Mar 5, 2021, 7:39:12 AM3/5/21
to Chromium Extensions, ilyaigpetrov, Cyrille
Thanks Ilya for your reply, very much appreciated!

A few clarifications regarding what I'm trying to achieve with my extension and the issue I'm facing: 

- My extension runs an ajax call every x minutes to a server and based on the result, displays the updated information in the extension pop-up window.
- I was able to implement all of this logic with my ajax call made from popup.js and it works perfectly fine.
- The only limitation I currently face is that the extension user has to click on the extension icon for the popup.js/html script to be executed, (which is expected as you pointed out).
- I'm  trying to figure how to trigger the ajax call function when the browser is first launched (then rely on alarms api for the x minutes check).

Solution trial 1: I moved my ajax call and response logic from popup.js to background.js and included a chrome.runtime.onStartup.addListener. 
The problem with this approach is that background.js can't access my popup DOM and thus cannot display my updated information.

Solution trial 2: I kept my ajax call and response logic in popup.js. In background.js, I added a chrome.runtime.sendMessage within the chrome.runtime.onStartup.addListener. 
The problem with this approach is that popup.js "does not exist" per say and apparently not able to get the message from background.js to execute the ajax call.

It feels a bit like an chicken & egg problem, not sure what the right approach is!

Thanks!

Best,

Cyrille

PhistucK

unread,
Mar 5, 2021, 7:50:55 AM3/5/21
to Cyrille, Chromium Extensions, ilyaigpetrov
I think you need to use chrome.alarms for scheduling your AJAX call. It has a limitation, I think it runs every 10 minutes at a minimum, not 5 or similar, if it fits your purpose.

For making the information available to the popup (once it is opened), you can use indexedDB, or chrome.storage and load from those when the popup is opened.

For loading jQuery, you just have to importScript it (only assuming it knows how to work within workers, of course).

Another option that avoids most of the complexity is to create a visible tab (it does not have to be active) on startup, via the service worker, with an extension page and it can run like a manifest version 2 background page, only more visible to the user (you can put some placeholder text/image that tells the user not to worry about it (and re-open it if it closes, via a service worker, using chrome.tabs.onClosed or something similar).
Not the most beautiful solution to the user, but it does make it clear that it is always running.

You received this message because you are subscribed to the Google Groups "Chromium Extensions" group.
To unsubscribe from this group and stop receiving emails from it, send an email to chromium-extens...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/chromium-extensions/1947c3b4-8287-4c50-b10d-60bf097bf7e3n%40chromium.org.

Cyrille

unread,
Mar 5, 2021, 9:53:44 AM3/5/21
to Chromium Extensions, PhistucK, Chromium Extensions, ilyaigpetrov, Cyrille
Thanks Phistuck for your reply.

Yes I use chrome.alarms for scheduling my AJAX call. 

Based on further digging it looks like I should go Solution 1 + messaging and since I am currently making a ManifestV3 extension I understand I then have the following options: 
1. Either switch to a manifest V2 extension 2 so I can use Jquery in my background.js file.
2. Replace Jquery ajax call with a native XMLHttpRequest call in my background.js 

This would translate in: onstartup = 1 ajax call (to update the extension icon) and then whenever the user clicks on the pop-up either 1 ajax call  or read it from storage (if stored there) to get the latest info. 

ilyaigpetrov

unread,
Mar 5, 2021, 9:57:11 AM3/5/21
to Cyrille, Chromium Extensions, PhistucK
> Replace Jquery ajax call with a native XMLHttpRequest call in my background.js 

PhistucK

unread,
Mar 6, 2021, 3:27:36 PM3/6/21
to Cyrille, Chromium Extensions, ilyaigpetrov
If you are using jQuery basically for its $.ajax, I wholeheartedly recommend fetch, like ilyaigpetrov wrote. jQuery is totally an overkill for most things today.

PhistucK

Cyrille

unread,
Mar 8, 2021, 3:22:24 AM3/8/21
to Chromium Extensions, PhistucK, Chromium Extensions, ilyaigpetrov, Cyrille
Great, thank you all for the feedback, I'll give it a try!

Best,

Pedro Cabrera

unread,
Dec 28, 2021, 2:41:39 PM12/28/21
to Chromium Extensions, cyrille....@gmail.com, PhistucK, Chromium Extensions, ilyaigpetrov
Hi Cyrille, did you finally find a solution?
Thanks!!

Simeon Vincent

unread,
Jan 5, 2022, 9:54:22 PM1/5/22
to Pedro Cabrera, Chromium Extensions, cyrille....@gmail.com, PhistucK, ilyaigpetrov
I think other folks addressed Cyrille's question, but one other I'd like to highlight is that the way web_accessible_resources was declared in the first post will will not match any pages 

"web_accessible_resources": [{
"resources": ["lib/jquery.min.3.5.1.js"],
"matches": [],
"extension_ids": []
}],

Both "matches" and "extension_ids" are empty arrays here, meaning that the declared resources are not actually being exposed to any sites. To make this file accessible to all pages you will need to declare a match pattern in the "matches" array. For example:

"web_accessible_resources"
: [{
"resources": ["lib/jquery.min.3.5.1.js"],
"matches": ["*://*/*"]
}],

Simeon - @dotproto
Chrome Extensions DevRel


Reply all
Reply to author
Forward
0 new messages