Skip to main content
Manifest V3 service workers have no DOM. When background logic needs DOM parsing, audio playback, clipboard access, or another window-only API, Chrome’s answer is an offscreen document: an invisible extension page you create on demand with chrome.offscreen.

Setup

Request the permission in manifest.json:
manifest.json
The offscreen page is not a manifest entrypoint, so declare it through the pages/ special folder and Extension.js compiles it like any other HTML entry:
pages/offscreen.html

Create, reuse, close

Chrome allows one offscreen document per extension, and calling createDocument while one exists throws. The reliable pattern is an ensure function that checks for an existing document first:
background.ts
The creating lock matters: two events can race into ensureOffscreen before the document exists, and the second createDocument call would throw. Close it when the work is done to free memory:

Choosing a reason

The reasons array tells Chrome why the document exists. Common values: One behavior worth knowing: with AUDIO_PLAYBACK, Chrome closes the document automatically about 30 seconds after audio stops playing. For other reasons the document lives until you close it or the extension unloads.

Talking to the document

Offscreen documents use standard runtime messaging. Scope your messages so other surfaces ignore them:
pages/offscreen.ts

Firefox

Firefox does not implement chrome.offscreen. Its Manifest V3 background runs as an event page that already has DOM access, so the same DOM work runs directly in the background script there. Use browser-specific manifest fields and a capability check (typeof chrome.offscreen !== "undefined") to branch.

See also