Loading html into page element (chrome extension)

While the above solution does work, one thing to pay attention to is that you need to return true from the event handler so that the communication port can still be available after the $.ajax call succeeds.

see below for more information. https://code.google.com/p/chromium/issues/detail?id=307034


URL of a file inside an extenion folder has the following format:

chrome-extension://<ID>/topbar.html

You can get this path by running:

chrome.extension.getURL("topbar.html")

Now if you try to do:

$('#topbar').load(chrome.extension.getURL("topbar.html"));

it wouldn't let you because of cross-origin policy. Background pages don't have this limitation, so you would need to load HTML there and pass result to a content script:

content_script.js:

chrome.extension.sendRequest({cmd: "read_file"}, function(html){
    $("#topbar").html(html);
});

background.html:

chrome.extension.onRequest.addListener(function(request, sender, sendResponse) {
    if(request.cmd == "read_file") {
        $.ajax({
            url: chrome.extension.getURL("topbar.html"),
            dataType: "html",
            success: sendResponse
        });
    }
})

In a real world you probably would read topbar.html only once and then reuse it.


Pure js solution.

In your manifest.json:

{
  "manifest_version": 3,
  # [...]
  "web_accessible_resources": [{
      "matches": ["<all_urls>"],
      "resources": ["topbar.html"]
  }]
}

In your content.js:

async function load_toolbar() {
  let newElement = new DOMParser().parseFromString('<div id="toolbar"></div>', 'text/html').body.childNodes[0];
  let toolbar_url = chrome.runtime.getURL("toolbar.html");

  document.querySelector("body").appendChild(newElement);
  document.getElementById("toolbar").innerHTML = await (await fetch(toolbar_url)).text();
}

load_toolbar();