exit-intent-js
Version:
Lightweight, dependency-free JavaScript utility for detecting exit-intent. Fires a single custom event when the user looks like they're about to leave – based on time-on-page, idle time, mouse-leave, tab visibility & window blur. Perfect for pop-ups, surv
149 lines (118 loc) • 5.84 kB
Markdown
# Exit Intent Detection Library
[](https://www.npmjs.com/package/exit-intent-js) [](https://github.com/julesbravo/exit-intent-js/actions/workflows/ci.yml) [](LICENSE)
A lightweight, vanilla JavaScript library for detecting exit intent on web pages. Useful for showing popups, surveys, or capturing feedback before users leave your site.
## Features
- Detects exit intent via multiple signals:
- Time on page
- User idle time
- Mouse leaves window
- Tab/document visibility change
- Window loses focus (blur)
- Pages Viewed
- Fast upward scrolling
- Customizable options
- Simple API
- No dependencies
## Installation
Copy `src/exit-intent.js` into your project, or install via npm (if published):
```sh
npm install exit-intent-js
```
## Usage
```js
import observeExitIntent from './src/exit-intent';
const { destroy } = observeExitIntent({
eventName: 'my-exit-event',
timeOnPage: 10000,
debug: true
});
window.addEventListener('my-exit-event', e => {
console.log('Exit intent detected:', e.detail);
});
// To manually clean up listeners and timers:
// destroy();
```
## Options
| Option | Type | Default | Description |
|-------------------|----------|--------------|-----------------------------------------------------------------------------|
| `timeOnPage` | number | `15000` | Time (ms) spent on page before triggering exit intent. `0` disables. |
| `idleTime` | number | `8000` | Time (ms) idle (no interaction) before triggering. `0` disables. |
| `mouseLeaveDelay` | number | `1000` | Delay (ms) after mouse leaves window before triggering. `0` disables. |
| `tabChange` | boolean | `true` | Trigger when tab/document becomes hidden. |
| `windowBlur` | boolean | `true` | Trigger when window loses focus (user switches tabs/apps or minimizes). |
| `eventName` | string | `'exit-intent'` | Name of the custom event dispatched on window. |
| `debug` | boolean | `false` | Enable debug logging to console. |
| `pageViewsToTrigger` | number | `0` | Fire the exit-intent event immediately once the stored page-view counter reaches this threshold. `0` disables the feature. |
| `scrollUpThreshold` | number\|object | `{mobile: 200, desktop: 400}` | Minimum pixels scrolled up to trigger exit intent. Can be a number (legacy) or object with `mobile` and `desktop` properties for responsive thresholds. |
| `mobileBreakpoint` | number | `768` | Screen width threshold (px) for mobile detection. Used with responsive `scrollUpThreshold`. |
| `scrollUpInterval` | number | `100` | Interval (ms) to check scroll position for upward movement. |
By default the library stores a persistent page-view counter in `localStorage` under the key `exit-intent-page-views` and automatically increments that value every time the script is evaluated (i.e. on a full page load).
If you have a single-page-app (SPA) and want to increment the counter on client-side route changes, call:
```js
observeExitIntent.incrementPageViews(); // bump by 1 (or pass a custom amount)
```
## Responsive Scroll Thresholds
The `scrollUpThreshold` option supports responsive thresholds for different device types:
### Object Format (Recommended)
```js
observeExitIntent({
scrollUpThreshold: {
mobile: 200, // Lower threshold for mobile devices (≤ 768px)
desktop: 400 // Higher threshold for desktop devices (> 768px)
},
mobileBreakpoint: 768 // Screen width threshold for mobile detection
});
```
### Legacy Number Format (Still Supported)
```js
observeExitIntent({
scrollUpThreshold: 300 // Same threshold for all devices
});
```
### Benefits of Responsive Thresholds
- **Mobile devices**: Lower threshold (200px) makes it easier to trigger on touch devices where scrolling patterns differ
- **Desktop devices**: Higher threshold (400px) reduces false positives from mouse wheel scrolling
- **Automatic detection**: The library automatically detects device type based on screen width
- **Backward compatibility**: Existing code using number values continues to work
## Exit Intent Reasons
The custom event's `detail` property will be one of:
- `'timeOnPage'` — Time on page exceeded
- `'idleTime'` — User idle for too long
- `'mouseLeave'` — Mouse left window
- `'tabChange'` — Tab/document became hidden
- `'windowBlur'` — Window lost focus
- `'scrollUp'` — User scrolled up quickly
## Examples
### 1. Basic usage (vanilla JS)
```js
observeExitIntent({
timeOnPage: 5000,
idleTime: 3000,
mouseLeaveDelay: 500,
tabChange: true,
windowBlur: true,
scrollUpThreshold: {
mobile: 200, // 200px threshold for mobile devices
desktop: 400 // 400px threshold for desktop devices
},
mobileBreakpoint: 768,
scrollUpInterval: 50,
eventName: 'exit-intent',
debug: true
});
window.addEventListener('exit-intent', e => {
alert('Exit intent detected! Reason: ' + e.detail);
});
```
### 2. Triggering a Postscript Popup on exit-intent
If you use [Postscript](https://postscript.io/) for SMS pop-ups, you can open a popup only when exit intent is detected. A full working page lives in [`examples/postscript.html`](examples/postscript.html).
---
## Cleanup
The function returns an object with a `destroy` method to remove all listeners and timers:
```js
const { destroy } = observeExitIntent();
// ...
destroy();
```
## License
MIT