Capabilities · API
Idle Detection API: watching for user and screen inactivity
Published Updated
In one line: The Idle Detection API’s IdleDetector interface lets a page ask
whether the user has interacted with the screen or device within a given threshold,
and whether the screen is locked, firing a change event whenever either state flips.
Requesting permission
Section titled “Requesting permission”Per MDN, starting an IdleDetector requires the idle-detection permission, and
IdleDetector.requestPermission() requires transient user activation — it must be
called from within a user gesture, such as a click handler:
startButton.addEventListener('click', async () => { const permission = await IdleDetector.requestPermission(); if (permission !== 'granted') { console.error('Idle detection permission denied.'); return; } await startIdleDetector();});Starting the detector
Section titled “Starting the detector”start() takes a threshold in milliseconds and an optional AbortSignal. Per the
WICG specification, start() rejects with a TypeError when threshold is below
60,000ms (60 seconds) — there is no way to ask for finer-grained reporting:
async function startIdleDetector() { const controller = new AbortController(); const idleDetector = new IdleDetector();
idleDetector.addEventListener('change', () => { console.log(`User: ${idleDetector.userState}, Screen: ${idleDetector.screenState}`); });
await idleDetector.start({ threshold: 60_000, signal: controller.signal, });}userState reports "active" or "idle"; screenState reports "locked" or
"unlocked". Per MDN, both return null before start() is called, and start()
gives them their initial values.
Where it is supported
Section titled “Where it is supported”Per MDN’s compatibility data, IdleDetector ships only in Chromium-based browsers,
from Chrome version 94, and requires a secure context. Firefox and Safari do not
implement it.
Feature detection and fallback
Section titled “Feature detection and fallback”async function watchIdleState(onChange) { if (!('IdleDetector' in window)) { // Unsupported: there is no OS-level idle/lock state to report here, so // just report unknown instead of guessing. onChange({ userState: 'unknown', screenState: 'unknown' }); return; }
const permission = await IdleDetector.requestPermission(); if (permission !== 'granted') { onChange({ userState: 'unknown', screenState: 'unknown' }); return; }
const idleDetector = new IdleDetector(); idleDetector.addEventListener('change', () => { onChange({ userState: idleDetector.userState, screenState: idleDetector.screenState }); }); await idleDetector.start({ threshold: 60_000 });}Practical checklist
Section titled “Practical checklist”- Feature-detect with
'IdleDetector' in windowbefore referencing the class — it does not exist in Firefox or Safari. - Call
IdleDetector.requestPermission()from inside a user gesture; calling it without transient user activation fails per spec. - Do not pass a
thresholdbelow 60,000ms —start()rejects with aTypeErrorinstead of just reporting more slowly. - Treat
userStateandscreenStateasnullbeforestart()is called; do not read them synchronously right after construction. - Provide a working fallback experience for Firefox and Safari, which do not currently implement this API, rather than degrading silently.
Where to go next
Section titled “Where to go next”- Screen Wake Lock API — another device-state capability API.
- PWAs on Firefox — more on Firefox’s platform capability support.
Specifications
| Specification | Status |
|---|---|
| None. | |