Description
Use the offscreen
API to create and manage offscreen documents.
Permissions
offscreen
To use the Offscreen API, declare the "offscreen"
permission in the extension manifest. For example:
{
"name": "My extension",
...
"permissions": [
"offscreen"
],
...
}
Availability
Concepts and usage
Service workers don't have DOM access, and many websites have content security policies that
limit the functionality of content scripts. The Offscreen API allows the extension to use DOM
APIs in a hidden document without interrupting the user experience by opening new windows or
tabs. The runtime
API is the only extensions API
supported by offscreen documents.
Pages loaded as offscreen documents are handled differently from other types of extension pages.
The extension's permissions carry over to offscreen documents, but with limits on extension API
access. For example, because the chrome.runtime
API is the only
extensions API supported by offscreen documents, messaging must be handled
using members of that API.
The following are other ways offscreen documents behave differently from normal pages:
- An offscreen document's URL must be a static HTML file bundled with the extension.
- Offscreen documents can't be focused.
- An offscreen document is an instance of
window
, but the value of itsopener
property is alwaysnull
. - Though an extension package can contain multiple offscreen documents, an installed extension can only have one open at a time. If the extension is running in split mode with an active incognito profile, the normal and incognito profiles can each have one offscreen document.
Use chrome.offscreen.createDocument()
and
chrome.offscreen.closeDocument()
to create and close an offscreen
document. createDocument()
requires the document's url
, a reason, and a justification:
chrome.offscreen.createDocument({
url: 'off_screen.html',
reasons: ['CLIPBOARD'],
justification: 'reason for needing the document',
});
Reasons
For a list of valid reasons, see the Reasons section. Reasons are set during
document creation to determine the document's lifespan. The AUDIO_PLAYBACK
reason sets the
document to close after 30 seconds without audio playing. All other reasons don't set lifetime limits.
Examples
Maintain the lifecycle of an offscreen document
The following example shows how to ensure that an offscreen document exists. The
setupOffscreenDocument()
function calls runtime.getContexts()
to find
an existing offscreen document, or creates the document if it doesn't already exist.
let creating; // A global promise to avoid concurrency issues
async function setupOffscreenDocument(path) {
// Check all windows controlled by the service worker to see if one
// of them is the offscreen document with the given path
const offscreenUrl = chrome.runtime.getURL(path);
const existingContexts = await chrome.runtime.getContexts({
contextTypes: ['OFFSCREEN_DOCUMENT'],
documentUrls: [offscreenUrl]
});
if (existingContexts.length > 0) {
return;
}
// create offscreen document
if (creating) {
await creating;
} else {
creating = chrome.offscreen.createDocument({
url: path,
reasons: ['CLIPBOARD'],
justification: 'reason for needing the document',
});
await creating;
creating = null;
}
}
Before sending a message to an offscreen document, call setupOffscreenDocument()
to make sure
the document exists, as demonstrated in the following example.
chrome.action.onClicked.addListener(async () => {
await setupOffscreenDocument('off_screen.html');
// Send message to offscreen document
chrome.runtime.sendMessage({
type: '...',
target: 'offscreen',
data: '...'
});
});
For complete examples, see the offscreen-clipboard and offscreen-dom demos on GitHub.
Before Chrome 116: check if an offscreen document is open
runtime.getContexts()
was added in Chrome 116. In earlier versions of
Chrome, use clients.matchAll()
to check for an existing offscreen document:
async function hasOffscreenDocument() {
if ('getContexts' in chrome.runtime) {
const contexts = await chrome.runtime.getContexts({
contextTypes: ['OFFSCREEN_DOCUMENT'],
documentUrls: [OFFSCREEN_DOCUMENT_PATH]
});
return Boolean(contexts.length);
} else {
const matchedClients = await clients.matchAll();
return matchedClients.some(client => {
return client.url.includes(chrome.runtime.id);
});
}
}
Types
CreateParameters
Properties
-
justification
string
A developer-provided string that explains, in more detail, the need for the background context. The user agent _may_ use this in display to the user.
-
reasons
Reason[]
The reason(s) the extension is creating the offscreen document.
-
url
string
The (relative) URL to load in the document.
Reason
Enum
"TESTING" "AUDIO_PLAYBACK" "IFRAME_SCRIPTING" "DOM_SCRAPING" "BLOBS" "DOM_PARSER" "USER_MEDIA" "DISPLAY_MEDIA" "WEB_RTC" "CLIPBOARD" "LOCAL_STORAGE" "WORKERS" "BATTERY_STATUS" "MATCH_MEDIA" "GEOLOCATION"
A reason used for testing purposes only.
Specifies that the offscreen document is responsible for playing audio.
Specifies that the offscreen document needs to embed and script an iframe in order to modify the iframe's content.
Specifies that the offscreen document needs to embed an iframe and scrape its DOM to extract information.
Specifies that the offscreen document needs to interact with Blob objects (including URL.createObjectURL()
).
Specifies that the offscreen document needs to use the DOMParser API.
Specifies that the offscreen document needs to interact with media streams from user media (e.g. getUserMedia()
).
Specifies that the offscreen document needs to interact with media streams from display media (e.g. getDisplayMedia()
).
Specifies that the offscreen document needs to use WebRTC APIs.
Specifies that the offscreen document needs to interact with the Clipboard API.
Specifies that the offscreen document needs access to localStorage.
Specifies that the offscreen document needs to spawn workers.
Specifies that the offscreen document needs to use navigator.getBattery.
Specifies that the offscreen document needs to use window.matchMedia.
Specifies that the offscreen document needs to use navigator.geolocation.
Methods
closeDocument()
chrome.offscreen.closeDocument(
callback?: function,
)
Closes the currently-open offscreen document for the extension.
Parameters
-
callback
function optional
The
callback
parameter looks like:() => void
Returns
-
Promise<void>
Promises are supported in Manifest V3 and later, but callbacks are provided for backward compatibility. You cannot use both on the same function call. The promise resolves with the same type that is passed to the callback.
createDocument()
chrome.offscreen.createDocument(
parameters: CreateParameters,
callback?: function,
)
Creates a new offscreen document for the extension.
Parameters
-
parameters
The parameters describing the offscreen document to create.
-
callback
function optional
The
callback
parameter looks like:() => void
Returns
-
Promise<void>
Promises are supported in Manifest V3 and later, but callbacks are provided for backward compatibility. You cannot use both on the same function call. The promise resolves with the same type that is passed to the callback.