javascriptgoogle-chrome-extension

How to import html2canvas in Chrome extension


I have created an extension to get a capture of the body with the following code, but I get an error message.

Please help.

[Error message]

Uncaught (in promise) TypeError: Failed to fetch dynamically imported module: chrome-extension://... /js/content.js

[Source code] manifest.json

  "content_scripts": [
    {
        "matches": ["<all_urls>"],
        "js": [ "script.js" ]
    }
  ],
  "web_accessible_resources": [
    {
      "matches": ["<all_urls>"],
      "resources": [
          "js/content.js",
          "js/html2canvas.js"
      ]
    }
  ]

content.js

import html2canvas from './html2canvas';

let target_element = document.getElementsByTagName('body')[0];
let button_element = document.createElement('button');
button_element.setAttribute("id", "captcha-btn");
button_element.innerHTML = 'test';
target_element.prepend(button_element);

let target_pankuzu_element = document.getElementsByTagName('body')[0];
let img_element = document.createElement('img');
img_element.setAttribute("id", "result");
target_pankuzu_element.prepend(img_element);

const BUTTON_CLICK_EVENT= document.getElementById('captcha-btn');
BUTTON_CLICK_EVENT.addEventListener('click', () => {
    html2canvas(document.getElementsByTagName('body')[0],{}).then(function(canvas){
        document.getElementById('result').src = canvas.toDataURL();
    })
});

script.js

(async() => {
    const src = chrome.runtime.getURL("js/content.js");
    const contentMain = await import(src);
})();

To be executable without error.


Solution

  • import html2canvas from './html2canvas';

    Content scripts can't import other extension scripts using relative paths, because they run in the origin of the website, so you should have built this script using webpack or a similar bundler.

    However, there's no need for modules here.

    1. Remove script.js and web_accessible_resources.
    2. List the scripts in content_scripts and they will run in the specified order.

    manifest.json:

      "content_scripts": [{
        "matches": ["<all_urls>"],
        "js": ["js/html2canvas.js", "js/content.js"]
      }],
    

    content.js:

    // no need for import, html2canvas.js already ran and created a global
    html2canvas(document.querySelector("#capture")).then(canvas => {
      document.body.appendChild(canvas)
    });