Performance > ngx-idle-monitor
A lightweight Angular service for tracking user activity, managing session timeouts, and syncing idle state across tabs.
Angular Idle Monitor
A robust, performance-optimized Angular service for tracking user activity, handling session timeouts, and synchronizing idle states across multiple browser tabs using localStorage.
🚀 Features
- 🔄 Multi-Tab Sync: Activity in one tab resets the timer in all other open tabs of the same application.
- ⚡ Performance Focused: Event listeners run outside of
NgZoneto prevent unnecessary change detection cycles. - ⚠️ Warning System: Emit events before the final timeout occurs (perfect for "Stay logged in?" modals).
- 🌐 SSR Friendly: Safe for use in Universal/SSR applications (checks for
isPlatformBrowser). - 📡 Keepalive Support: Supports heartbeat functions or Observables to ping your backend during activity.
📦 Installation
- install the
idle-monitorinto your Angular project bynpm install ngx-idle-monitor. - Provide the monitor in your
app.config.ts(for Standalone) orAppModule.
Standalone (App Config)
import { provideIdleMonitor } from './shared/idle-monitor';
export const appConfig: ApplicationConfig = {
providers: [
provideIdleMonitor({
timeout: 15 * 60 * 1000, // 15 minutes
warningDuration: 60 * 1000, // 1 minute warning
autostart: true
})
]
};
Usage
Inject the IdleMonitor service into your root component to listen for state changes.
import { Component, inject } from '@angular/core';
import { IdleMonitor } from './shared/idle-monitor';
@Component({
selector: 'app-root',
template: `<router-outlet></router-outlet>`
})
export class AppComponent {
private idle = inject(IdleMonitor);
constructor() {
// 1. Handle Inactivity (e.g., Logout)
this.idle.inactive.subscribe(() => {
console.log('Session expired due to inactivity.');
// Perform logout redirect here
});
// 2. Handle Warning Period (e.g., Show Countdown Modal)
this.idle.warning.subscribe((msLeft) => {
const seconds = Math.floor(msLeft / 1000);
console.warn(`Inactivity warning: ${seconds}s remaining.`);
});
// 3. Handle Return to Activity
this.idle.active.subscribe(() => {
console.log('User is active again! Logic to hide modal can go here.');
});
}
}
Configuration Options (IdleMonitorConfig)
| Property | Type | Default | Description |
|---|---|---|---|
timeout |
number |
7200000 (2h) |
Total idle time allowed in milliseconds. |
warningDuration |
number |
0 |
Time in ms before timeout to start emitting warnings. |
events |
string[] |
['click', 'mousemove', 'keydown', 'touchstart', 'scroll'] |
DOM events that trigger activity. |
debounce |
number |
200 |
Debounce time for activity events to save resources. |
minUpdateInterval |
number |
1000 |
Minimum time between writing new activity to storage. |
keepaliveFn |
Function |
() => {} |
Executes on activity. Can return an Observable. |
autostart |
boolean |
true |
Start monitoring as soon as the app loads. |
How It Works
Multi-Tab Synchronization
The service utilizes the StorageEvent API. When activity is detected in Tab A, it updates a timestamp in localStorage (idle-monitor-last-activity). Tab B listens for this storage key change. If Tab B sees a newer timestamp, it automatically resets its own internal timer. This prevents the user from being timed out while they are active in a different window.
Performance & Zone Management
By using runOutsideAngular, high-frequency events like mousemove and scroll do not trigger Angular's change detection engine. The service only re-enters the Angular Zone when it is time to emit a state change (active, inactive, or warning), ensuring your app stays performant even with constant mouse movement.
Manual Time Checking
When a tab is hidden and then becomes visible again (or regains focus), the service performs a manual check against the lastActivity timestamp. This ensures that if the timeout occurred while the computer was asleep or the tab was backgrounded, the inactive event fires immediately upon return.