Idle Detection API
Published
Idle Detection API — the IdleDetector interface lets a page ask whether the user has
interacted with the device within a given threshold, and whether the screen is
locked, firing a change event whenever either state flips.
Browser & ecosystem support
Section titled “Browser & ecosystem support”- Legend
- Yes
- Partial
- Flag
- No
- Unknown
| Browser / Platform | Support | Versions | Confidence | Source | Notes |
|---|---|---|---|---|---|
| Chrome (Desktop) | Yes | 94 | high | source | — |
| Chrome (Android) | Yes | 94 | high | source | 1 |
| Edge (Desktop) | Yes | 114 | high | source | — |
| Firefox (Desktop) | No | — | high | source | 2 |
| Firefox (Android) | No | — | high | source | 34 |
| Safari (macOS) | No | — | high | source | 5 |
| Safari (iOS) | No | — | high | source | 67 |
| Samsung Internet | Yes | 17.0 | high | source | 8 |
| WebView (Android) | Yes | 94 | high | source | 9 |
- Derived by browser-compat-data mirroring from Chrome.
- No Firefox support is recorded in browser-compat-data.
- No Firefox for Android support is recorded in browser-compat-data.
- Derived by browser-compat-data mirroring from Firefox.
- No Safari support is recorded in browser-compat-data.
- No Safari on iOS support is recorded in browser-compat-data.
- Derived by browser-compat-data mirroring from Safari.
- Derived by browser-compat-data mirroring from Chrome Android.
- Derived by browser-compat-data mirroring from Chrome Android.
How to use it
Section titled “How to use it”The specification says start() fails unless the idle-detection permission has been granted,
and IdleDetector.requestPermission() rejects without transient user activation — so it belongs
inside a user-gesture handler. start() takes a threshold in milliseconds:
// Minimal, self-contained: create the control the handler needs, then wire it up.const startButton = document.createElement('button');startButton.type = 'button';startButton.textContent = 'Watch idle state';document.body.append(startButton);
startButton.addEventListener('click', async () => { const permission = await IdleDetector.requestPermission(); if (permission !== 'granted') return;
const detector = new IdleDetector(); detector.addEventListener('change', () => { console.log(`User: ${detector.userState}, Screen: ${detector.screenState}`); }); await detector.start({ threshold: 60_000 });});userState reports "active" or "idle"; screenState reports "locked" or "unlocked".
How to detect it at runtime
Section titled “How to detect it at runtime”Check for IdleDetector on window before referencing the class, and take an explicit
fallback branch when it is absent:
async function watchIdleState(onChange) { if (!('IdleDetector' in window)) { // IdleDetector is unavailable, so report unknown and leave the feature's UI hidden. onChange({ userState: 'unknown', screenState: 'unknown' }); return; }
const permission = await IdleDetector.requestPermission(); if (permission !== 'granted') { onChange({ userState: 'unknown', screenState: 'unknown' }); return; }
const detector = new IdleDetector(); detector.addEventListener('change', () => { onChange({ userState: detector.userState, screenState: detector.screenState }); }); await detector.start({ threshold: 60_000 });}Practical checklist
Section titled “Practical checklist”- Per MDN, the API is available only in secure contexts, so an insecure origin does not
expose
IdleDetectorat all. - Call
IdleDetector.requestPermission()from inside a user gesture — per MDN it requires transient user activation. - Per the WICG specification,
start()rejects with aTypeErrorwhenthresholdis below 60,000 ms; there is no way to ask for finer-grained reporting. - The WICG specification initializes
userStateandscreenStatetonull, so do not read them right after constructing the detector. - Per MDN’s browser-compat-data, Firefox and Safari do not implement
IdleDetector, so those browsers take the fallback branch above.
Where to go next
Section titled “Where to go next”For the full reference (permission model, change event, threshold rules), see
Idle Detection API.
See also Screen Wake Lock for the inverse problem — keeping the screen awake rather than observing when it locks.
← Back to the Compatibility explorer.