Skip to main content

useIdleDetection

Location: src/hooks/useIdleDetection.js

Overview

Tracks user activity (mouse movement, clicks, key presses, touch, scroll, wheel) and sets an isIdle flag after a configurable period of inactivity. Activity handlers are throttled to fire at most once per second to avoid excessive state updates.

Used to support features like auto-locking, session management, and privacy-related behaviors aligned with the platform's "Privacy Is Infrastructure" invariant.

Signature

function useIdleDetection(
timeoutMinutes?: number,
enabled?: boolean
): {
isIdle: boolean,
resetIdle: () => void,
lastActivity: number
}

Parameters

ParameterTypeRequiredDefaultDescription
timeoutMinutesnumberNo5Minutes of inactivity before the user is considered idle.
enabledbooleanNotrueWhether idle detection is active. When false, isIdle is always false and no listeners are attached.

Return Value

PropertyTypeDescription
isIdlebooleantrue when the user has been inactive for longer than the configured timeout. Resets to false on any user activity.
resetIdle() => voidManually reset the idle state and activity timestamp.
lastActivitynumberTimestamp (from Date.now()) of the most recent detected user activity.

Tracked Events

The hook listens for the following events on the window object (with { passive: true }):

  • mousemove
  • mousedown
  • keydown
  • touchstart
  • scroll
  • wheel

All events are throttled to a maximum of one update per second.

Usage

function AutoLockWrapper({ children }) {
const { isIdle } = useIdleDetection(10); // 10 minutes

if (isIdle) {
return <LockScreen />;
}

return children;
}

With custom timeout and manual reset

function SessionManager() {
const { isIdle, resetIdle, lastActivity } = useIdleDetection(15, true);

useEffect(() => {
if (isIdle) {
showIdleWarning();
}
}, [isIdle]);

return (
<div>
<p>Last activity: {new Date(lastActivity).toLocaleTimeString()}</p>
{isIdle && (
<div>
<p>You appear to be away.</p>
<button onClick={resetIdle}>I am here</button>
</div>
)}
</div>
);
}

Last updated: 2026-02-07