First-Click PopUnder Script (Lightweight & Vanilla JS)
Need a simple popunder that fires only once per visitor and doesn’t drag in a million dependencies? This little vanilla JavaScript snippet attaches to the first click on your page, opens a popunder, and then gets out of the way.
What this script does
- Fires only on the first real click from a visitor
- Uses vanilla JS (no jQuery or frameworks)
- Stores a flag in localStorage so it won’t spam the same user
- Lets you exclude login / checkout / payment / “no-pop” links
- Tries to behave like a popunder by blurring the new window
Important. Modern browsers are aggressive about blocking popups & popunders. This snippet tries to behave nicely, but whether it opens / goes under the main window is ultimately up to the browser and user settings.
Step 1 – Create first-click-popunder.js
Create a new file in your web root called first-click-popunder.js and paste the code below into it.
Update POPUNDER_URL and the exclude list to match your site.
// first-click-popunder.js
(function () {
// ─────────────────────────────────────────────
// CONFIG (EDIT THESE)
// ─────────────────────────────────────────────
// Where to send the popunder visitor
var POPUNDER_URL = 'https://example.com/your-offer-or-ad';
// Unique key for this script in localStorage
var STORAGE_KEY = 'vibe_popunder_fired_v1';
// Fire at most once per X minutes (set to 0 for "once per browser")
var FIRE_INTERVAL_MINUTES = 60; // 60 = once per hour per browser
// CSS selectors / patterns to EXCLUDE from triggering the popunder
// - Any click inside these elements will be ignored
var EXCLUDE_SELECTORS = [
'a[data-no-popunder]', // manually mark safe links
'a[href*="logout"]',
'a[href*="login"]',
'a[href*="checkout"]',
'a[href*="paypal.com"]'
];
// ─────────────────────────────────────────────
// INTERNALS (NO NEED TO EDIT)
// ─────────────────────────────────────────────
if (!POPUNDER_URL) {
return; // misconfigured, do nothing
}
if (!('localStorage' in window)) {
// Older / weird browser, still try but no frequency limiting
attachHandler();
return;
}
try {
var stored = window.localStorage.getItem(STORAGE_KEY);
if (stored) {
var data = JSON.parse(stored);
if (data && data.ts && FIRE_INTERVAL_MINUTES > 0) {
var now = Date.now();
var diffMs = now - data.ts;
var limitMs = FIRE_INTERVAL_MINUTES * 60 * 1000;
if (diffMs < limitMs) {
// Too soon since last fire; bail out.
return;
}
}
}
} catch (e) {
// If localStorage is blocked or broken, just continue and try once.
}
attachHandler();
function attachHandler() {
// Use capture so we see the click as early as possible
document.addEventListener('click', handleClick, true);
}
function handleClick(evt) {
// Only react to real left-clicks, no modifiers
if (evt.defaultPrevented) return;
if (evt.button !== 0) return; // left button only
if (evt.metaKey || evt.ctrlKey || evt.shiftKey || evt.altKey) return;
var target = evt.target;
if (!target) return;
// Skip if click is inside an excluded element
for (var i = 0; i < EXCLUDE_SELECTORS.length; i++) {
var sel = EXCLUDE_SELECTORS[i];
try {
if (target.closest && target.closest(sel)) {
return;
}
} catch (e) {
// Bad selector should not kill everything
}
}
// At this point, we want to fire the popunder once.
document.removeEventListener('click', handleClick, true);
try {
var w = window.open(POPUNDER_URL, '_blank');
if (w) {
// Try to behave like a popunder by moving focus back
w.blur();
window.focus();
}
} catch (e) {
// Blocked by browser or popup blocker
}
// Record timestamp if we have localStorage
try {
if ('localStorage' in window) {
window.localStorage.setItem(STORAGE_KEY, JSON.stringify({
ts: Date.now()
}));
}
} catch (e) {
// Ignore storage errors
}
}
})();
Step 2 – Include it on your pages
Right before your closing </body> tag, include the script like this:
<script src="/first-click-popunder.js"></script>
If your file lives in a different path, update the src accordingly (for example
/js/first-click-popunder.js).
Step 3 – Mark links that should NEVER trigger a popunder
For login, logout, checkout, or other sensitive actions, you can add a
data-no-popunder attribute so clicks on those links are always ignored:
<a href="/members/login" data-no-popunder="1">Member Login</a>
<a href="/checkout" data-no-popunder="1">Checkout</a>
<a href="https://paypal.com/..." data-no-popunder="1">Pay with PayPal</a>
You can also tweak the EXCLUDE_SELECTORS array in the script if you prefer
to match by URL pattern instead of adding attributes.
Controlling how often it fires
By default this snippet fires at most once per hour per browser:
[code] // Fire at most once per X minutes (set to 0 for "once per browser") var FIRE_INTERVAL_MINUTES = 60; [/code>- Set it to
0for “once ever per browser”. - Set it to
1440for “once per day”. - Set it to
5or10if you want it more aggressive (but watch user experience).
Disclaimer. Popups and popunders can be annoying and may be limited or blocked by browsers, extensions, or ad policies. Use this script at your own risk and only where it makes sense for your audience. Always test on a staging site first and keep backups.