Documentation
Get up and running
One script tag, then build popups in the dashboard. Replace YOUR_SITE_TOKEN with the token shown in your dashboard.
The install snippet
Drop this single line of JavaScript before </body> on any page where you want popups to fire. The script self-initializes, fetches your active popups, and renders the right one based on your targeting rules.
<script
src="https://www.popthelead.com/embed/popup.v1.js"
data-site-token="YOUR_SITE_TOKEN"
defer></script>We recommend pinning to popup.v1.js rather than popup.js — v1 is API-stable; the unpinned file may update.
WordPress
Three options, easiest first:
- WPCode (recommended): install the free WPCode plugin → Code Snippets → Header & Footer → paste the snippet into Footer → Save.
- Customizer: some themes have Appearance → Customize → Additional Code → Footer. Paste there.
- Theme files: edit
footer.phpin your child theme and paste before</body>. Don't edit the parent theme — your changes get wiped on update.
Shopify
- From the admin: Online Store → Themes → … → Edit code.
- Open
layout/theme.liquid. - Paste the snippet directly before the closing
</body>tag and save.
Cart-value targeting works automatically on Shopify if the theme exposes window.__cartTotal. Otherwise add <script>window.__cartTotal = {{ cart.total_price | divided_by: 100.0 }};</script> to the same template.
Webflow
- Site Settings → Custom Code.
- Paste the snippet into the Footer Code field.
- Save and republish your site.
Page-specific install is also available under Page Settings → Custom Code if you only want popups on certain pages.
Plain HTML / any framework
Drop the snippet before </body>. Works in static HTML, Astro, Eleventy, Hugo, Gatsby, plain React/Vue/Svelte SPAs, Next.js, and just about anywhere else. No initialization call needed — the script is self-booting.
For SPAs that change routes client-side without a full reload, the popup re-evaluates triggers on the initial load only. SPA route-change re-arming is on the roadmap (see Roadmap). For now, the simplest workaround is to render popups on the routes where they matter and accept the first-load semantics.
ESP integrations
Connect Klaviyo, Mailchimp, Omnisend, ActiveCampaign, ConvertKit, or Drip from the dashboard Integrations tab. When a visitor submits a popup, their email is queued for delivery to your ESP. Failures retry on an exponential backoff (30s → 2m → 10m → 1h → 6h, then dead-letter) and are visible per-site in the dashboard.
API keys are encrypted at rest using AES-256-GCM. We never log key contents and never expose them back through the API.
Webhooks (Agency plan)
Configure a webhook URL on the site settings page. We POST a JSON payload on every conversion:
{
"event": "conversion",
"idempotencyKey": "del_clz1abcd234efghij",
"email": "lead@example.com",
"popupId": "...",
"popupName": "Welcome Discount",
"variantId": "...",
"metadata": { "url": "https://your-site.com/", "referrer": "" },
"timestamp": "2026-05-05T12:00:00.000Z"
}Your endpoint should respond with HTTP 2xx within 8 seconds. We'll retry up to 5 times with backoff if you return 5xx, time out, or are unreachable.
Idempotency. Every delivery carries a stable idempotencyKey (and an Idempotency-Key request header) that is identical across retries of the same conversion. Use it as the dedupe key on your side — if you've already accepted that key, return 2xx and ignore the duplicate.
Troubleshooting
Popup never appears. Open your browser DevTools console:
- If you see
[PopUp] data-site-token missing, the snippet is wrong — paste it again. - If you see a network error on
/api/embed/<token>, the token doesn't match a site or the site has no published popups. - If everything looks loaded but nothing shows, check frequency capping: try in an incognito window, or clear
localStoragekeys starting withpu_. - Ad-blockers occasionally block third-party scripts. We don't use third-party tracking, but uBlock Origin's anti-popup list may flag us — affected users will simply not see popups, which we treat as the user's choice.
Popup appears but my CSS looks wrong. The host page's CSS can occasionally bleed into the popup (the embed renders in the light DOM today — see Roadmap). The primary solution is the Custom CSS field on the variant: override specific selectors with higher specificity (e.g. .ptl-popup .my-button { ... }), and use !important only for properties your site sets aggressively.
Strict CSP on host site. Allow script-src https://www.popthelead.com and connect-src https://www.popthelead.com. Inline styles applied by the popup currently require 'unsafe-inline' in style-src.
Consent & GDPR
Pop the Lead does not set tracking cookies. We use localStorage for per-popup variant assignment and frequency capping — first-party data on the visitor's own browser, not shared with us beyond what your popup explicitly captures (typically email + optional phone).
For lead capture itself, you remain the data controller. The Consent checkbox element renders a GDPR-compliant opt-in line you can wire to your privacy policy. For double opt-in, set up a confirmation flow in your ESP (Klaviyo and Mailchimp both support it natively).
Data subject requests: lead data is owned by you, exported and deleted from your ESP. Account-level data export and deletion endpoints are available — see our privacy policy.
Roadmap
Features that exist in our backlog but are not in the embed today. Treat anything below as “not yet shipped” — don't depend on it in production code.
- SPA route-change re-arm. A documented
popthelead:resetcustom event that lets single-page apps re-evaluate triggers on client-side navigation. Until this ships, the embed evaluates triggers once on initial load. - Shadow DOM isolation. Render the popup inside a shadow root so the host page's CSS cannot bleed in. Today the popup runs in the light DOM; the primary workaround is the Custom CSS field on each variant (see Troubleshooting).
Need one of these sooner? Email support — we prioritize by paying customers' needs.
Stuck? Email support — we typically reply within one business day.
