8
Hooks

useIdleTimeout

A hook that detects user inactivity and triggers callbacks for idle and active states.

useIdleTimeout

The useIdleTimeout hook detects when a user has been inactive for a specified period and provides callbacks for both idle and active states. It’s useful for implementing features like automatic logout, session timeouts, screensavers, or any functionality that should trigger after a period of inactivity.

👋

You are active

Last activity: 0 seconds ago

Move your mouse, press a key, or scroll to show activity.
The idle timeout is set to 5 seconds for this demo.

Installation

Install the useIdleTimeout hook using:

npx axionjs-ui add hook use-idle-timeout

File Structure

use-idle-timeout.ts

Parameters

PropTypeDefault
timeout
number
Required
onIdle
() => void
() => {}
onActive
() => void
() => {}
events
string[]
['mousedown', 'mousemove', 'keypress', 'scroll', 'touchstart']
initialState
boolean
false

Return Value

PropTypeDefault
isIdle
boolean
-

Examples

Session Timeout Warning

Implement a session timeout warning with a countdown:

👨‍💻

User Session Active

Stay inactive for 10 seconds to see the timeout warning.

Auto-Save Draft

Automatically save draft content when the user is idle:

function AutoSavingEditor() {
  const [content, setContent] = useState('');
  const [lastSaved, setLastSaved] = useState(null);
  const [isSaving, setIsSaving] = useState(false);
  
  // Save the draft content
  const saveDraft = useCallback(async () => {
    if (!content) return;
    
    setIsSaving(true);
    
    try {
      // Simulate API call
      await new Promise(r => setTimeout(r, 500));
      // await api.saveDraft(content);
      
      setLastSaved(new Date());
    } catch (error) {
      console.error('Failed to save draft:', error);
    } finally {
      setIsSaving(false);
    }
  }, [content]);
  
  // Use the idle timeout to trigger auto-save
  useIdleTimeout({
    timeout: 3000, // 3 seconds - shorter for demonstration
    onIdle: saveDraft,
  });
  
  return (
    <div className="editor-container">
      <div className="editor-header">
        <h2>Draft Editor</h2>
        {lastSaved && (
          <span className="save-indicator">
            Last saved: {lastSaved.toLocaleTimeString()}
          </span>
        )}
        {isSaving && <span className="save-indicator">Saving...</span>}
      </div>
      
      <textarea
        value={content}
        onChange={(e) => setContent(e.target.value)}
        placeholder="Start typing your draft..."
        rows={10}
      />
      
      <div className="editor-footer">
        <button onClick={saveDraft} disabled={isSaving}>
          Save Manually
        </button>
        <p className="auto-save-note">
          Note: Your draft will be automatically saved after 3 seconds of inactivity.
        </p>
      </div>
    </div>
  );
}

Screensaver or Idle State UI

Show a screensaver or change the UI when the user is idle:

function IdleUI() {
  const [lastActiveTime, setLastActiveTime] = useState(new Date());
  
  const handleActive = useCallback(() => {
    setLastActiveTime(new Date());
  }, []);
  
  const isIdle = useIdleTimeout({
    timeout: 30000, // 30 seconds
    onActive: handleActive,
  });
  
  return (
    <div className={`app-container ${isIdle ? 'idle-mode' : ''}`}>
      {isIdle ? (
        <div className="screensaver">
          <div className="floating-logo" />
          <p className="screensaver-text">Click anywhere to continue</p>
        </div>
      ) : (
        <div className="app-content">
          <h1>My Application</h1>
          <p>Last active: {lastActiveTime.toLocaleTimeString()}</p>
          <div className="app-dashboard">
            {/* Your app content here */}
          </div>
        </div>
      )}
    </div>
  );
}

Use Cases

  • Session Management: Warn users before their session expires
  • Auto-Logout: Automatically log out inactive users for security
  • Auto-Save: Save drafts or progress when the user is idle
  • Screensavers: Display different content when the user is inactive
  • Resource Conservation: Pause resource-intensive operations during inactivity
  • Chat Applications: Set user status to away after inactivity
  • Analytics: Track user engagement and active session time
  • Presentations: Pause slideshows during inactivity
  • Media Playback: Pause videos/music when the user is idle
  • Security Features: Lock sensitive information after inactivity

Activity Detection

The hook monitors user activity through various browser events:

  • Mouse Events: mousedown, mousemove
  • Keyboard Events: keypress, keydown
  • Touch Events: touchstart, touchmove
  • Window Events: scroll, resize

You can customize this list based on your application’s needs:

useIdleTimeout({
  timeout: 60000,
  // Only track mouse and keyboard, ignore scrolling
  events: ['mousedown', 'mousemove', 'keypress', 'keydown'],
  onIdle: handleIdle,
});

Performance Considerations

  • The hook uses event throttling to minimize performance impact during rapid user activity
  • Consider the impact of frequent callback executions in onActive
  • For very short timeout values (< 1 second), be aware of potential performance implications

Accessibility

When implementing idle detection features:

  • Ensure time-based redirects or session expirations provide ample warning
  • Make activity detection inclusive of keyboard-only users
  • Consider users with motor disabilities who may have limited cursor movement
  • Provide clear visual and textual feedback about timeout/idle status
  • Avoid triggering disruptive idle state changes during form completion

Browser Compatibility

The hook uses standard event listeners that work across all modern browsers. There are no specific browser compatibility concerns.

Best Practices

  • Choose an appropriate timeout duration for your use case
  • Provide clear feedback when a timeout is approaching
  • Allow users to easily extend their session
  • Use idle detection for non-critical enhancement features rather than core functionality
  • Consider user preferences when implementing auto-save features
  • Test with keyboard-only navigation
  • Ensure mobile compatibility by including touch events

On this page