Search code examples
javascriptgoogle-chromegoogle-chrome-extensionchrome-extension-manifest-v3jsdelivr

Using CDN Javascript libraries in Chrome extensions (manifest v3)


I have a simple Chrome extension that analyzes the page using ChatGPT and creates Google Calendar invite. The full source is here but here's the core of the code which reads the current page's text when clicked:

manifest.json:

{
  "manifest_version": 3,
  "name": "Chrome AI",
  "version": "0.0.1",
  "action": {
    "default_popup": "index.html",
    "default_icon": "chrome_ai.png"
  },
  "permissions": [
    "tabs",
    "activeTab",
    "scripting",
    "storage"
  ],
  "host_permissions": ["<all_urls>"]
}

index.html:

<!doctype html>
<html lang="en">
<head>
    <title>Chrome AI</title>
    <script src="vendors/jquery-3.7.1.min.js"></script>
    <script defer src="index.js"></script>
</head>
<body>
<button id="gcal">Create Google Calendar Invite</button>
<code id="logs"></code>
</body>
</html>

index.js

$('#gcal').on('click', executeInTab(() => document.body.innerText).then(text => $('#logs').append(text)))

executeInTab = (f) => chrome.tabs.query({active: true, lastFocusedWindow: true})
  .then(([tab]) => chrome.scripting.executeScript({target: {tabId: tab.id}, function: f}))
  .then(([{ result }]) =>  result)

But, as you can see this requires me to download and check in jquery under vendors/jquery-3.7.1.min.js. Since it is a bad practice to check in library dependencies to your repo (same reason you don't checkin your node_modules), I prefer to simply use a CDN like jsdelivr to host my libraries. But, when I try to add <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/jquery.min.js"></script> I get following error:

Before someone closes this question as a duplicate, here is why other answers don't work:

  1. In this the accepted answer is for manifest v2 whereas I am on manifest v3. The v3 answers posted there simply don't work (my code posted here does the suggestion from there).
  2. This asks how to load the jquery into the active tab window and not really as a dependency of the extension itself
  3. This, this, this and this asks how to load libraries into the content and background workers and not into the popup window itself. FWIW, these are duplicates of each other and NOT duplicate of this question!
  4. This one is poorly phrased and has no answers and uses manifest v2

Solution

  • In order to improve security, Chrome has removed support for CDNs in extensions with Manifest V3, or any other way of using remotely hosted JavaScript.

    They have a few solutions they recommend instead:

    • You can also load external libraries at runtime by adding them to the files array when calling scripting.executeScript(). You can still load data remotely at runtime:
      chrome.scripting.executeScript({
        target: {tabId: tab.id},
        files: ['jquery.min.js']
      });
      
    • Just bundle the file as part of the extension. I know this is viewed as bad practice according to the article you found, but it has a minimal impact for the user, and the Chrome documentation doesn't seem to have a problem with it.
      <script src="./jquery.min.js"></script>