webdevpuneet.com

Screen Wake Lock Toggle — Free navigator.wakeLock Demo

Screen Wake Lock Toggle · Buttons · Plain HTML, CSS & JS · Live preview

CategoryButtons

Copy & paste

Source Code

<section class="swl-wrap">
  <span class="swl-tag">navigator.wakeLock · screen sentinel</span>
  <h1>Keep screen awake</h1>
  <p id="swlStatus">Turn this on while you're reading a recipe or following a workout, and your screen won't sleep.</p>

  <div class="swl-card">
    <div class="swl-row">
      <div>
        <strong>Screen wake lock</strong>
        <span id="swlSubtext">Off — your screen will sleep normally.</span>
      </div>
      <button class="swl-toggle" id="swlToggle" role="switch" aria-checked="false" aria-label="Toggle screen wake lock">
        <span class="swl-knob"></span>
      </button>
    </div>
    <div class="swl-dot-row">
      <span class="swl-dot" id="swlDot"></span>
      <span id="swlDotLabel">Inactive</span>
    </div>
  </div>

  <p class="swl-note">The Wake Lock API automatically releases whenever the tab is hidden (switching apps, locking the phone) — this demo listens for visibility changes and re-acquires the lock the moment the page becomes visible again, which is the real quirk anyone shipping this needs to handle.</p>
</section>

Extend with AI

Take This Snippet Further With AI

The AI prompt for this one is for Patreon supporters ($3 a month, 7 days free), along with a site with no ads. Supporters enter the passcode once and it is remembered in this browser.

· Become a supporter

What's included

Features

Real wakeLock.request call
Genuinely prevents display sleep, not a decorative switch.
WakeLockSentinel tracking
Holds and releases the actual lock handle correctly.
Visibility auto-reacquire
Handles the API's real auto-release-on-hide quirk.
Release event listener
Detects unexpected releases, not just user-initiated ones.
Disabled, not fake, when unsupported
No silent no-op toggle on unsupported browsers.
Named failure reasons
Surfaces the actual DOMException name on refusal.
Live status dot
A glanceable indicator separate from the longer status text.
Accessible switch semantics
role="switch" and aria-checked stay in sync with real state.

About this UI Snippet

Screen Wake Lock Toggle — Real Wake Lock With the Visibility Quirk Handled

Screenshot of the Screen Wake Lock Toggle snippet rendered live

This toggle calls the genuine Screen Wake Lock API — navigator.wakeLock.request('screen') — to actually prevent a device's display from sleeping while the toggle is on, the kind of control a recipe app or workout timer needs so the screen doesn't dim mid-instruction. Unlike a purely decorative switch, this one either does the real thing or plainly says it can't, because a wake lock toggle that silently does nothing is worse than no toggle at all.

Requesting and holding the lock

acquireLock() calls navigator.wakeLock.request('screen'), which resolves with a WakeLockSentinel — a live handle representing the held lock — wrapped in a try/catch since the browser can refuse the request (commonly a NotAllowedError, and some browsers refuse outright on very low battery). Success flips the UI to its "on" state and updates the status text to confirm the lock is genuinely active, not just that a switch was clicked.

The auto-release quirk, handled honestly

The one behavior every real implementation of this feature has to account for: a wake lock automatically releases the instant its document becomes hidden — switching apps, locking the phone, or backgrounding the tab all silently drop it. This snippet listens for the sentinel's own release event to detect that, and separately listens for visibilitychange on the document to re-acquire the lock the moment the page becomes visible again, but only if the user still wants it on (tracked in userWantsLock). Skipping this step is the single most common bug in real wake-lock implementations — the toggle looks "on" but the screen sleeps anyway the next time the user glances away.

No supported, no fake toggle

If 'wakeLock' in navigator is false, the toggle is disabled outright with an explanatory status line, rather than left interactive and doing nothing when clicked — matching the honesty standard set by this library's canvas audio frequency bars snippet, which never leaves a capability-gated control pretending to work. A visually-active-looking toggle that silently fails to keep the screen awake would defeat the entire purpose of the control.

A visible status dot

Beyond the toggle itself, a small status dot and label track the sentinel's actual state, so at a glance — even without reading the longer status sentence — it's clear whether the lock is genuinely held right now. Pair this with an uptime status page or status pill for the same "live indicator" pattern applied elsewhere in a dashboard.

Customizing it

Auto-request the lock on page load for a kiosk-style display, add a countdown showing how long the lock has been held, or combine it with a dark mode toggle for a late-night reading mode.

Step by step

How to Use

  1. 1
    Paste HTML, CSS, and JSAn off-state toggle with a status dot renders.
  2. 2
    Click the toggle to turn it onnavigator.wakeLock.request('screen') is called live.
  3. 3
    Switch tabs or lock your phoneThe lock auto-releases — a real browser behavior.
  4. 4
    Return to the tabThe visibilitychange listener re-acquires the lock automatically.
  5. 5
    Click the toggle offThe sentinel is released and the screen can sleep again.
  6. 6
    Try it in an unsupported browserThe toggle disables itself with a clear explanation.

Real-world uses

Common Use Cases

Recipe and cooking apps
Keep the screen on through a multi-step recipe, with a real navigator.wakeLock.request('screen') call that genuinely prevents sleep.
Workout and timer apps
Prevent the display sleeping mid-set without the user touching the phone, re-acquiring the lock when the page becomes visible again.
Presentation and kiosk modes
Pair with a status pill showing whether the lock is active, detecting unexpected releases through the sentinel's release event.
Reading apps
Combine with a dark mode toggle for night reading, handling the API's quirk of auto-releasing when a tab is hidden.
Always-on dashboards
Keep a status dashboard visible on a wall display, or hold a video call waiting room on screen before a meeting starts.

Got questions?

Frequently Asked Questions

That shouldn't happen with this snippet — but it's the exact bug that occurs if a wake lock implementation doesn't handle the API's biggest quirk: the lock automatically releases the instant the document is hidden (switching tabs, locking the phone, backgrounding the app). This snippet listens for visibilitychange and re-acquires the lock automatically when the page becomes visible again, as long as the toggle is still meant to be on.

The Wake Lock API (navigator.wakeLock) isn't supported in every browser. This snippet checks 'wakeLock' in navigator before doing anything, and if it's missing, disables the toggle outright with an explanatory message rather than leaving it clickable and silently doing nothing — a toggle that looks functional but has no effect is worse than one that's honestly unavailable.

No — requesting a wake lock requires a real user action to trigger it in this snippet (clicking the toggle), and the browser itself will show some visible indication that a page is holding a wake lock in many implementations. The lock is also always scoped to that specific document and releases automatically the moment the tab is closed, navigated away from, or hidden.

Browsers can refuse a wake lock request for reasons like critically low battery, an explicit user or system power-saving policy, or (in an embedded context) a permissions policy blocking the wake-lock feature for that frame. This snippet catches that rejection and shows the actual error name in the status text, then leaves the toggle in a clearly labeled off state rather than pretending the lock is held.

Store the WakeLockSentinel and a "user wants lock" boolean in refs (not state, since the sentinel is a live object rather than serializable data), and mirror the same acquireLock/releaseLock functions as event handlers. Add the visibilitychange listener in a mount effect and remove it in cleanup, and make sure to release any held lock on unmount so a component teardown doesn't leave a phantom lock active.