loading
Warning:
Experimental - Chromium only The IdleDetector API is experimental and currently implemented only in Chromium-based browsers (Chrome, Edge, Opera). Firefox and Safari do not support it. Always gate usage behind IsSupported.
Note:
Permission and user gesture Idle detection requires a secure context and the idle-detection permission. Call RequestPermission from a user-gesture handler (like the buttons below) - the browser rejects prompts that don't originate from user interaction.

Support check

IsSupported

Returns true when the runtime exposes IdleDetector. During prerender/SSR the check returns false rather than throwing, so defer it to OnAfterRenderAsync.

C#
@inject Bit.Butil.IdleDetector idleDetector

var supported = await idleDetector.IsSupported();
Live sample
support check output
Results will appear here when you interact with the samples.

Request permission

RequestPermission

Asks the browser for the idle-detection permission and returns the resulting PermissionState (Granted, Denied, Prompt or Unknown). Starting a detector without a granted permission fails.

C#
var state = await idleDetector.RequestPermission();

if (state is PermissionState.Granted)
{
    // safe to call Start
}
Live sample
permission output
Results will appear here when you interact with the samples.

Watch idle state

Start

Starts watching for idle changes with the given threshold in seconds (the spec minimum is 60 - smaller values are clamped). The handler receives an IdleState with UserState (active/idle) and ScreenState (locked/unlocked) on every change. Dispose the returned ButilSubscription to stop.

C#
private ButilSubscription? _sub;

_sub = await idleDetector.Start(60, state =>
{
    // state.UserState:   "active" | "idle"
    // state.ScreenState: "unlocked" | "locked"
});

// stop watching:
await _sub.DisposeAsync();
Live sample
Threshold (seconds, minimum 60)
Live state Not watching.
idle watch output
Results will appear here when you interact with the samples.

API reference

Member
Signature
Description
IsSupported
ValueTask<bool> IsSupported()
True when the runtime exposes IdleDetector. Returns default (false) during prerender/SSR instead of throwing.
RequestPermission
ValueTask<PermissionState> RequestPermission()
Asks the browser for the idle-detection permission and returns the new permission state.
Start
Task<ButilSubscription> Start(int threshold, Action<IdleState> handler)
Starts watching for idle changes. Thresholds below 60 seconds are clamped to 60. Dispose the returned subscription to stop.
DisposeAsync
ValueTask DisposeAsync()
Stops every active detector and releases the JS callback reference. Called automatically on scope/circuit teardown.
InvokeIdleDetector
void InvokeIdleDetector(Guid id, IdleState state)
JSInvokable interop plumbing for state changes - not intended for app code.
IdleState.UserState
string UserState { get; set; }
The user's activity state: active or idle.
IdleState.ScreenState
string ScreenState { get; set; }
The screen's lock state: locked or unlocked.
An unhandled error has occurred. Reload 🗙