In a Safari Web Extension using Manifest V3, how can a content script access an HTML file that is bundled with the extension (e.g., to inject it as an iframe)? Safari's CSP seem to prevent the use of browser.runtime.getURL() in the MAIN world — is there a recommended way to load such resources securely?
How did we do? We’d love to know your thoughts on this year’s conference. Take the survey here
Accessing Extension Resources from Content scripts
You’re right to use browser.runtime.getURL()
, but note that it’s only available in privileged extension contexts like content scripts and the background page — not the page’s main world.
To inject an extension frame:
- Declare the file as a web-accessible resource in your manifest:
"web_accessible_resources": [{
"resources": ["frame.html"],
"matches": ["*://*/*"]
}]
- Use a content script to resolve the URL and inject it:
const iframe = document.createElement('iframe');
iframe.src = browser.runtime.getURL('frame.html');
document.body.appendChild(iframe);
This approach ensures the frame loads correctly and securely from your extension.