Key takeaways
- An exit intent Shopify popup fires the moment a shopper looks like they are about to leave, giving you one last chance to catch an email or offer a discount.
- On desktop it triggers when the cursor races toward the browser chrome. Mobile has no real mouse exit, so you fall back to the back button, a fast scroll up, or a timeout.
- The build is small: a mouseout detector, a modal, and frequency capping in localStorage so it fires once per session and stays gone after a dismissal.
- Google’s intrusive-interstitial guidance mostly targets pop-ups that block content on entry from search on mobile. An exit popup that fires as the user leaves is generally lower risk, but the design rules still matter.
- Fudge builds the popup as native theme code with proper triggers and capping, so you avoid a heavy third-party app.
An exit intent Shopify popup is a pop-up that appears when a visitor signals they are about to abandon the page. It is one of the few ways to speak to a shopper at the exact moment they are leaving, before the tab closes and the session is gone for good.
This guide covers what exit intent is, the CRO case for it, how to build it natively on desktop and mobile, and the Google penalty rules you need to respect so the popup helps conversions without hurting rankings.
Why you can trust us
We have worked in the Shopify space for over four years and helped hundreds of brands tune their storefronts. We build Fudge, an AI storefront editor with a 5.0 rating on the Shopify App Store, so we work on the same theme layer a popup lives on and see exactly what breaks when one is built badly.
What is an exit-intent pop-up?
An exit-intent popup is a modal that stays dormant until the visitor shows intent to leave, then appears once. It is a behaviour trigger, not a timer that fires the second someone lands.
On desktop, “intent to leave” is read from the mouse. When the cursor moves up and out of the top of the viewport toward the address bar, back button, or a different tab, the browser fires a mouseout or mouseleave event with the pointer above the page. That upward exit is the classic exit-intent signal.1
The content is usually a single focused offer: a discount code for a first order, a newsletter sign-up, or a reminder about the items still sitting in the cart.
The CRO case
The value is timing. A standard popup interrupts a shopper who is still browsing. An exit popup interrupts nobody, because it only appears once the visitor has already decided to go.
That makes it a low-cost recovery layer. A visitor who was going to leave with nothing instead leaves an email address, or reconsiders because of a discount. You are not stealing attention from an engaged shopper, you are catching one on the way out the door.
Exit intent is one tactic inside a wider conversion strategy. For the full picture, see our Shopify CRO guide. For the email-capture side specifically, see how to add an email pop-up in Shopify.
How to build an exit-intent pop-up on Shopify
You do not need a dedicated app. A native build has three parts: the exit detector, the modal, and the frequency cap that stops it becoming annoying.
1. Detect exit on desktop
The reliable desktop signal is the cursor leaving the top edge of the document. Listen for mouseleave on the document and check that the pointer is at or above the top of the viewport.
document.addEventListener("mouseleave", (event) => {
// clientY <= 0 means the cursor exited past the top edge
if (event.clientY <= 0) {
showExitPopup();
}
});
Checking clientY <= 0 matters. Without it you would fire the popup any time the cursor left the page in any direction, including moving down to the taskbar, which is not an exit signal.
2. Handle the mobile problem
Mobile has no cursor, so there is no true mouseout to detect. A desktop exit-intent script does nothing useful on a phone, and most Shopify traffic is mobile.
The honest answer is that mobile exit intent is an approximation. You pick a proxy signal instead:
| Signal | How it reads as “leaving” | Watch out for |
|---|---|---|
| Back-button press | history.pushState then a popstate listener catches the back tap | Can feel manipulative if it blocks navigation |
| Fast upward scroll | A quick scroll toward the top suggests heading for the address bar | Easy to misfire on normal browsing |
| Inactivity timeout | No touch for N seconds implies disengagement | Not really exit, just idleness |
None is as clean as the desktop signal. The back-button approach is the closest to real intent, but treat it with care: never fully trap the shopper on the page, and let the browser back action still work.
3. Cap the frequency so it fires once
An exit popup that reappears on every page, every session, is a fast way to earn a bounce. Store a flag so it fires once and respects a dismissal.
const SEEN_KEY = "exit_popup_seen";
function showExitPopup() {
// already shown or dismissed this session, do nothing
if (localStorage.getItem(SEEN_KEY)) return;
openModal();
localStorage.setItem(SEEN_KEY, "1");
}
Use localStorage for a cap that persists across visits, or sessionStorage if you only want to suppress it for the current session. When the shopper closes or converts on the popup, that same flag keeps it from coming back.
The rule is simple: honour the dismissal. If someone closes the popup, they have answered. Do not ask again on the next page load.
Do exit-intent pop-ups hurt SEO?
This is the part most guides get wrong, so here is the accurate version.
Google published guidance on intrusive interstitials that can make content harder to reach. It applies mainly to pages where content is accessed from search on mobile, where a pop-up blocks the main content either as the page loads or immediately after.2
What the guidance flags as a problem:
- A pop-up that covers the main content right as the visitor arrives from a search result.
- A standalone interstitial the user has to dismiss before they can read anything.
- A layout where the above-the-fold area is mostly the interstitial rather than the content.
What Google describes as generally lower risk:
- Interstitials required by law, such as cookie consent or age verification.
- Login dialogs on content that is not meant to be publicly indexed.
- Banners that use a reasonable amount of space and are easy to dismiss.
An exit-intent popup sits closer to the safe side, because it fires as the user is leaving, not as they arrive from search. It does not block the content on entry, which is the behaviour the guidance is aimed at.
Treat this as best-practice design guidance, not a guaranteed ranking drop. There is no published percentage penalty to quote, and you should be sceptical of any guide that invents one. Build the popup to fire on exit, keep it easy to close, and you stay well within the intent of the rules.
Design and UX rules for exit pop-ups
A popup that converts and a popup that annoys are separated by a few details.
- Never fire on entry. The whole point is that it triggers on exit intent, not on a timer the second the page loads.
- Make it obvious to dismiss. A clear close button, a click on the backdrop, and the
Escapekey should all close it. A trapped shopper is a lost shopper. - Trap focus only while it is open. A modal should hold keyboard focus while visible so tab order stays inside it, then return focus to the page on close. This is the one place a focus trap is correct, and it must release the moment the popup closes.
- Add the right ARIA. Use
role="dialog"witharia-modal="true"and a label so screen readers announce it as a dialog. - Do not stack pop-ups. If a cookie banner, a chat widget, and a newsletter modal all fire together, you have a wall of overlays. Audit what already appears before adding another.
Get these right and the popup reads as a helpful last offer rather than an obstacle. For a newsletter-focused variant of the same pattern, see our guide to the Shopify newsletter popup.
App vs native: the tradeoff
You can add an exit popup with an app in a few clicks, and for a non-technical store that is a fair starting point. The tradeoffs are the familiar ones: a monthly fee, extra JavaScript on every page, a popup that may not match your theme, and a dependency that takes the popup with it when you uninstall.
Native code avoids all four. The catch is that someone has to write the detector, the modal, the frequency cap, and the accessibility details correctly. That is the gap the next section fills.
Where Fudge fits
Fudge is an AI storefront editor that writes native theme code. You describe the popup in plain language: “add an exit-intent popup that offers a 10% discount when a desktop visitor moves to leave, with a back-button fallback on mobile, that only shows once per session.” It writes the Liquid, CSS, and JavaScript directly into your theme.
Because the output is native, there is no third-party widget rendering over your store, no extra app script on every page, and no monthly popup fee. The frequency capping and the exit triggers are built in, so it fires once and honours a dismissal.
And because it is theme code, it survives uninstall. Cancel Fudge and the popup stays exactly where it is, the opposite of an app-rendered element that vanishes when you remove the app. The same holds for anything else you build with the Shopify store editor.
FAQ
On desktop it listens for the cursor leaving the top of the page. A mouseleave event on the document with clientY at or below zero means the pointer has moved up toward the browser chrome, which is the classic exit signal. Mobile has no cursor, so it relies on proxies like a back-button press, a fast scroll up, or an inactivity timeout.
Not in the same way. Phones have no mouse, so there is no true mouseout to catch. The common workaround is to watch for a back-button tap using the history API, since that is the closest thing to real exit intent. Just avoid fully trapping the visitor on the page or blocking normal navigation.
Generally it is lower risk than other pop-ups. Google's intrusive-interstitial guidance mainly targets pop-ups that block content on entry from search on mobile. An exit popup fires as the visitor leaves, not as they arrive, so it does not block the content the way the guidance is aimed at. Keep it easy to dismiss to stay safe.
Once per session at most, and never again after a dismissal. Store a flag in localStorage or sessionStorage when it shows, then check that flag before firing again. Repeatedly showing the same popup is a fast way to earn a bounce and annoy returning shoppers.
No. An exit popup is a small amount of native theme code: a mouseout detector, a modal with proper accessibility, and frequency capping. Apps are quicker to install but add a monthly fee, extra JavaScript, and a dependency that removes the popup on uninstall. Fudge builds the same thing as native code that stays after you cancel.
Keep it to one focused ask. A first-order discount, a newsletter sign-up, or a reminder of the items still in the cart all work well because they give a hesitating shopper a concrete reason to stay. Avoid stacking multiple offers or long forms, which add friction at the moment someone is already leaving.
Footnotes
-
MDN Web Docs, “Element: mouseleave event” and “Document: mouseout event” - the pointer leaving an element fires these events, and reading
clientY <= 0on the document identifies a cursor that has exited past the top edge of the viewport. https://developer.mozilla.org/en-US/docs/Web/API/Element/mouseleave_event ↩ -
Google Search Central Blog, “Helping users easily access content on mobile” (2016) - describes intrusive interstitials that can make content less accessible on pages where content is reached from search, and lists exceptions including interstitials required by legal obligation (such as cookie or age verification) and banners that use a reasonable amount of screen space and are easily dismissible. https://developers.google.com/search/blog/2016/08/helping-users-easily-access-content-on ↩