Screen Wake Lock API: keeping the screen on
In one line: The Screen Wake Lock API — navigator.wakeLock.request('screen') —
prevents the device from dimming or locking its screen while your app is active. It
requires a secure context, can only be acquired when the document is visible, and is
automatically released when the page is hidden (minimized, switched away from, or locked
by the OS).
Acquiring a wake lock
Section titled “Acquiring a wake lock”let wakeLock = null;
async function requestWakeLock() { try { wakeLock = await navigator.wakeLock.request('screen'); console.log('Wake lock acquired');
wakeLock.addEventListener('release', () => { console.log('Wake lock released'); wakeLock = null; }); } catch (err) { // DOMException: the request was refused (e.g., low battery) console.error(`Wake lock request failed: ${err.name} — ${err.message}`); }}Releasing a wake lock
Section titled “Releasing a wake lock”Release the lock explicitly when your use case ends — otherwise it drains the battery unnecessarily:
async function releaseWakeLock() { if (wakeLock) { await wakeLock.release(); wakeLock = null; }}Automatic release on page hide
Section titled “Automatic release on page hide”The browser automatically releases the wake lock whenever document.visibilityState
changes to 'hidden' — when the user switches tabs, minimizes the browser, or the
device goes to another app. The lock is not restored automatically when the page becomes
visible again. You must re-acquire it:
document.addEventListener('visibilitychange', async () => { if (document.visibilityState === 'visible' && userNeedsWakeLock) { await requestWakeLock(); }});Secure context (HTTPS)
Section titled “Secure context (HTTPS)”navigator.wakeLock is only available in secure contexts — HTTPS or localhost.
On plain HTTP the property is undefined.
No explicit permission prompt
Section titled “No explicit permission prompt”Unlike camera or microphone access, wake lock does not show a browser permission dialog.
The browser may silently deny the request in low-battery situations — your code should
handle the rejection gracefully (the catch block above).
Only 'screen' is currently defined
Section titled “Only 'screen' is currently defined”The spec defines 'screen' as the only valid wake lock type. A 'system' type was
considered (to prevent the CPU from sleeping while the screen is off) but is not exposed
to web pages in any current implementation.
Battery considerations
Section titled “Battery considerations”Holding a wake lock prevents the OS from dimming the screen, which significantly increases battery drain. Only request it when genuinely necessary (recipe display, presentation mode, real-time tracking) and always release it when the user is done or navigates away.
Browser & ecosystem support
Section titled “Browser & ecosystem support”See /compatibility/ for current per-browser data.
Decision framework
Section titled “Decision framework”| Decision question | Recommended action | Rationale |
|---|---|---|
| Recipe viewer, presentation, slideshow? | Acquire on start; release when the user dismisses the content. | Classic wake-lock use case — prevents screen timeout while hands are occupied. |
| Real-time tracking or fitness app? | Acquire when tracking starts; release when it stops. | The screen must stay on for the user to see live data. |
| Should wake lock survive tab switch? | No — the browser releases it automatically. Re-acquire in a visibilitychange listener. |
This is an intentional browser security invariant. |
| Need to keep CPU alive in background (SW sync)? | Use Background Sync or Periodic Background Sync. | Wake lock is screen-only and requires a visible document. |
| Low battery — what if the request fails? | Catch the rejection; fall back to a UI that tells the user to keep the screen awake manually. | The browser may refuse on energy grounds; your app should degrade gracefully. |
Practical checklist
Section titled “Practical checklist”- Serve the page over HTTPS —
navigator.wakeLockis undefined on plain HTTP. - Feature-detect:
if (!navigator.wakeLock)before callingrequest. - Re-acquire the lock in a
visibilitychangelistener when the document becomes visible again. - Release the lock explicitly when the feature is no longer needed.
- Catch the rejection from
request()— the browser may deny on low battery. - Communicate to users if the wake lock cannot be acquired so they can manually prevent screen timeout.