← Back toHTML DOM

Display a modal when users leave website

Written byPhuoc Nguyen
15 Sep, 2023
Level 2 — Intermediate
Retaining customers on a website can be challenging, but there's a trick that works like a charm: showing a subscription modal when they're about to leave. This not only boosts conversions but also improves customer retention on your website. In this post, we'll learn how to implement this feature using JavaScript DOM. Let's get started!

Tracking the mouse

As explained in this link, when users close or reload the browser, the `beforeunload` event is triggered. Unfortunately, it's not possible to customize the default warning message or UI with your own message.
Instead, we'll track the user's mouse movements and display a modal when we detect that they're about to leave the page.
To achieve this, we need to detect when the user is about to navigate away from the page. We can do this by tracking the `mouseleave` event across the entire `document`. Here's an example:
const handleMouseLeave = (e) => {
console.log('User left the page');

document.addEventListener('mouseleave', handleMouseLeave);
We track the `mouseleave` event instead of the `mousemove` event because it provides a more accurate indication of the user's intention to leave the page. The `mousemove` event fires continuously as long as the mouse is moving, which can result in false positives and impact performance.
In contrast, the `mouseleave` event only fires once when the mouse leaves the document area, giving us a more reliable signal to trigger our modal display logic. This approach not only provides a better user experience but also optimizes website performance by reducing unnecessary event handlers.
To kick off, we'll start by logging a message to the console whenever the user leaves the page. From there, we can move on to determining the position of the mouse. Luckily, we can easily achieve this using the `clientX` and `clientY` properties of the `MouseEvent` object. Check out the example below:
const handleMouseLeave = (e) => {
console.log('User left the page', e.clientX, e.clientY);
This code will log the `x` and `y` coordinates of the mouse every time it leaves the page. We can use these coordinates to check if the mouse is in the top-right corner of the browser. For instance, we can show a modal when the mouse is within 10 pixels of the top edge. You can customize this condition to suit your requirements.
Finally, we also remove the event handler when the condition is met. Removing the event handler may sound strange, but it's actually a good practice that can optimize performance. By doing this, the page no longer needs to track the mouse, resulting in smoother and faster user experience.
Here's how you could handle the `mouseleave` event:
const handleMouseLeave = (e) => {
if (e.clientX < 10) {
// Show the modal

// Stop tracking the mouse
document.removeEventListener('mouseleave', handleMouseLeave);

Use cookies or local storage to remember modal dismissal

When we add a modal that appears when the user moves their mouse to the top-right corner of the browser, we want to make sure they're not bombarded with it every time they visit the page. To avoid this, we can use cookies or local storage to remember if the user has dismissed the modal and prevent it from showing up again.
To make this happen, we'll add an event listener to the modal element that listens for when the user clicks the Close button. When they do, we can set a cookie or local storage value that tells the website not to show the modal again. Here's an example:
const COOKIE_NAME = 'exit-popup';

const closeButton = document.getElementById('closeButton');

const closeModal = () => {
// Hide the modal ...

// Set cookie value indicating that modal should not appear again
const date = new Date();
date.setTime(date.getTime() + 365*24*60*60*1000);
document.cookie = `${COOKIE_NAME}=true; expires=${date.toUTCString()}`;

closeButton.addEventListener('click', closeModal);
This code adds an event listener to the Close button in our modal element. When the button is clicked, it sets a cookie named `exit-popup` with a value of `true`. The cookie is set to expire in one year.
To set the expiration date, we create a new `Date` object and add 1 year's worth of milliseconds to it. Then we convert the resulting date to UTC format using the `toUTCString()` method and use it as the value for the `expires` attribute of the cookie. This ensures that the cookie will expire at the specified time and will be removed from the user's browser.
Before showing the modal, we check for the existence of this cookie using the `document.cookie` property. If it contains a value indicating that the cookie exists, we assume that the user has already dismissed the modal and skip showing it again.
Here's an example implementation for you to try out:
const hasModalShown = () => {
const cookie = `; ${document.cookie}`.split(`; ${COOKIE_NAME}=`).pop().split(';').shift();
return cookie === 'true';
The `mouseleave` event handler should check both the mouse position and whether the modal has been displayed properly.
const handleMouseLeave = (e) => {
if (e.clientY < 10 && !hasModalShown()) {
// Show the modal ...
You can use local storage, in addition to cookies, to check and indicate whether the modal has been displayed.
Check out our demo below: try moving your mouse over the demo area and then to the top. You'll see that the modal appears.
Good practice
When you're designing a subscription modal, it's crucial to keep in mind that users might find popups intrusive or irritating. To ensure that your modal is well-received by visitors, think about offering an incentive for signing up, like a discount code or a free trial period. This will encourage users to subscribe and make the process more enjoyable for them.


In conclusion, adding a subscription modal to your website can be a powerful way to increase conversions and retain customers. By tracking the user's mouse position and displaying the modal when they're about to leave, you can create an interactive feature that engages the user and motivates them to sign up.

See also

If you found this post helpful, please consider giving the repository a star on GitHub or sharing the post on your favorite social networks 😍. Your support would mean a lot to me!

Questions? 🙋

Do you have any questions about front-end development? If so, feel free to create a new issue on GitHub using the button below. I'm happy to help with any topic you'd like to learn more about, even beyond what's covered in this post.
While I have a long list of upcoming topics, I'm always eager to prioritize your questions and ideas for future content. Let's learn and grow together! Sharing knowledge is the best way to elevate ourselves 🥷.
Ask me questions

Recent posts ⚡

Newsletter 🔔

If you're into front-end technologies and you want to see more of the content I'm creating, then you might want to consider subscribing to my newsletter.
By subscribing, you'll be the first to know about new articles, products, and exclusive promotions.
Don't worry, I won't spam you. And if you ever change your mind, you can unsubscribe at any time.
Phước Nguyễn