Skip to content

API in Capabilities

Screen Wake Lock API

Published

Newly available since 2025-03W3C

navigator.wakeLock.request("screen") asks the operating system not to dim or lock the display while the document stays visible, and resolves with a WakeLockSentinel that you release yourself or that the browser releases for you the moment the page is hidden. The lock is the right tool for a recipe view, a presentation, or a live tracking screen; it does nothing for background work, because a hidden document can neither hold nor request one.

Chrome 84, Edge 84, Firefox 126, and Safari 16.4 on macOS implement the API without caveats. Safari on iOS 16.4 to 18.3 is recorded as partial in browser-compat-data: the lock has no effect in a standalone Home Screen web app (WebKit bug 254545), and the entry lists iOS 18.4 as the first full release.

navigator.wakeLock.request()
navigator.wakeLock.request(type)
sentinel.release()

request() returns a Promise<WakeLockSentinel>. release() on the sentinel returns a Promise<undefined> and fires a release event on the sentinel when the lock is gone, whoever released it. Both interfaces are [SecureContext] and exposed on Window only: navigator.wakeLock is undefined on http:// origins other than localhost, and workers have no wake lock at all.

request() takes one optional argument; the sentinel it resolves with exposes three members and one event.

Name Type Required Description
type WakeLockType (enum) No, defaults to "screen" The only value the specification defines is "screen". A "system" type (keep the CPU awake with the screen off) was discussed and dropped; passing it is a WebIDL enum violation.
WakeLockSentinel member Type Description
released boolean (read-only) false while the lock is held; true after release() resolves or after the browser released it. Chrome 87 added the attribute (Chrome 84 to 86 shipped the sentinel without it).
type WakeLockType (read-only) Echoes the requested type, "screen".
release() Promise<undefined> Removes this sentinel from the document’s active locks and releases the platform lock when no other sentinel of the same type remains.
release event Event Fired once per sentinel when it is released, including releases the browser performs on page hide, document unload, or OS intervention.

Several sentinels can be live at once; the platform lock is released when the last one is. The browser also releases every sentinel when document.visibilityState becomes "hidden" and does not restore it when the page becomes visible again.

request() rejects with a DOMException or a TypeError. Every rejection the specification defines carries the same name.

Exception Condition
NotAllowedError The document is not fully active; or the screen-wake-lock Permissions Policy denies the document (default allowlist 'self'); or the browser denies this lock type for the document; or document.visibilityState is "hidden" at call time or by the time the permission check finishes; or the screen-wake-lock permission resolves to "denied".
TypeError type is not a member of the WakeLockType enum (WebIDL conversion fails before the algorithm starts).

A low battery or a power-saving mode is a reason the specification lets the browser deny the lock (section 12, Security considerations), and in Chromium that denial surfaces as NotAllowedError. Failure further down, at the operating-system level, is deliberately hidden: the specification notes that a lock the OS refused is indistinguishable from an acquired one, so the promise still resolves and released stays false. release() does not reject; calling it on a sentinel that is already released resolves immediately.

Both examples feature-detect navigator.wakeLock and run a fallback when it is missing (Firefox before 126, Safari before 16.4, Android WebView builds that strip the permission).

Holding the screen during a workout and re-acquiring after a tab switch

Section titled “Holding the screen during a workout and re-acquiring after a tab switch”

The lock is lost whenever the page is hidden, so the visibilitychange listener requests it again when the page returns and the workout is still running. When the API is absent the app shows a one-line hint instead of silently letting the screen time out.

let sentinel = null;
let workoutRunning = false;
async function keepScreenOn() {
if (!('wakeLock' in navigator)) {
document.querySelector('#hint').textContent =
'Raise your screen timeout in system settings; this browser has no wake lock.';
return;
}
try {
sentinel = await navigator.wakeLock.request('screen');
sentinel.addEventListener('release', () => {
sentinel = null;
});
} catch (err) {
console.warn(`${err.name}: ${err.message}`);
}
}
document.querySelector('#start').addEventListener('click', async () => {
workoutRunning = true;
await keepScreenOn();
});
document.querySelector('#stop').addEventListener('click', async () => {
workoutRunning = false;
await sentinel?.release();
});
document.addEventListener('visibilitychange', () => {
if (document.visibilityState === 'visible' && workoutRunning && !sentinel) {
keepScreenOn();
}
});

sentinel?.release() is safe after the browser already released the lock: the release listener has set sentinel to null, so the optional chain skips the call.

A UI control that claims the screen is being kept awake has to follow the sentinel, not the click, because the browser can release the lock without the user touching the checkbox. Reading released in the release handler keeps the two in step.

const box = document.querySelector('#keep-awake');
let sentinel = null;
box.disabled = !('wakeLock' in navigator);
box.addEventListener('change', async () => {
if (box.checked) {
try {
sentinel = await navigator.wakeLock.request('screen');
sentinel.addEventListener('release', () => {
box.checked = !sentinel.released; // false once the browser lets go
});
} catch (err) {
box.checked = false; // rejected: hidden page, policy, or denial
}
} else {
await sentinel?.release();
}
});

Disabling the checkbox when navigator.wakeLock is missing tells the user up front that the option is unavailable here rather than failing on the first toggle.

Specifications

SpecificationStatus
Screen Wake LockW3C
Screen Wake Lock API: request() methodW3C
Screen Wake Lock API: release() methodW3C
  • Legend
  • Yes
  • Partial
  • Flag
  • No
  • Unknown
Browser / PlatformSupportVersionsConfidenceSourceNotes
Chrome (Desktop)Yes84highsource—
Chrome (Android)Yes84highsource1
Edge (Desktop)Yes84highsource2
Firefox (Desktop)Yes126highsource—
Firefox (Android)Yes126highsource3
Safari (macOS)Yes16.4highsource—
Safari (iOS)Partial16.4 → 18.4highsource4
Samsung InternetYes14.0highsource5
WebView (Android)Yes84highsource6
OperaYes73lowsource—
  1. Derived by browser-compat-data mirroring from Chrome.
  2. Derived by browser-compat-data mirroring from Chrome.
  3. Derived by browser-compat-data mirroring from Firefox.
  4. Does not work in standalone Home Screen Web Apps. See bug 254545 (https://webkit.org/b/254545#c32).
  5. Derived by browser-compat-data mirroring from Chrome Android.
  6. Derived by browser-compat-data mirroring from Chrome Android.

Source data: /compatibility/wake-lock.json · Global usage: 91 % (StatCounter 2026-05)

Source: spec · MDN · Last verified 2026-10-03 · Confidence: low (computed from sources)