new Worker(new URL("./worker.js", import.meta.url)) through the bundler default for a web target. The call emits a separate worker chunk at the root of dist/<browser>/, and the compiled call points at that chunk through chrome.runtime.getURL(). That part works.
The browser is what refuses. A worker script has to come from the same origin as the document that creates it. The document behind a content script is the host page, so both forms below fail.
What a content script actually gets
This content script compiles cleanly and fails at runtime:https://example.com, Chromium reports:
web_accessible_resources does not lift the restriction. It controls whether the page may load the file, not whether the file may become a worker for a foreign origin.
This was measured on Chromium with a content script on a public page. Firefox
and Safari were not measured, so treat the errors above as Chromium behavior.
Run the worker from a page that the extension owns
A popup, an options page, a side panel, and an offscreen document all load from thechrome-extension:// origin. A worker created there is same-origin, so both forms work with no extra setup:
The blob workaround, and its two conditions
When the work has to stay in the page, fetch the worker source and construct the worker from a blob URL. A blob inherits the page origin, so the browser accepts it:extension build does not add the worker chunk to web_accessible_resources, so declare the file yourself in manifest.json:
fetch fails with TypeError: Failed to fetch, and the request shows as chrome-extension://invalid/.
The host page CSP has to allow blob workers. A page that sends worker-src 'self' blocks the blob, and the failure is quiet. The constructor returns normally, then the worker fails through onerror with an empty message:
try/catch around new Worker never sees it. Attach an onerror handler and treat it as the real failure signal.
Choosing between the three
- An extension page needs no setup, and both forms work there.
- A content script with a blob needs a manifest entry and a permissive page CSP.
- A content script with an extension URL is refused, and nothing changes that.
Next steps
- Read Offscreen documents for background work without a visible page.
- Read Web accessible resources for the manifest entry.
- Read Content scripts for what else the page origin limits.

