Popup Generator
A popup generator builds the modal you want and hands you the code to embed it. Set the title, message, button and colours, choose a trigger and how often it may reappear, and the Embed Code panel prints a single script tag pointing at popup.min.js with your settings as data attributes — data-trigger, data-delay, data-bg and the rest.
Content
Trigger and behaviour
Customize
Presets
Live Preview
Embed Code
Popular Tools
About Popup Generator
The form is in four blocks. Content takes the Title, Message, Button Text and Button URL. Trigger & Behavior chooses between Timed Delay, Scroll %, Exit Intent and On Page Load, with a Delay in seconds or a scroll percentage as appropriate, a Frequency of Every Visit, Once Per Session, Once Per Day or Once Forever, and a Fade or Slide animation. The style block sets Background, Text Color, Button Color and a border radius slider, plus the Overlay Backdrop, Close on Overlay Click and Show branding switches. Four presets — Newsletter, Discount, Dark and Exit Intent — fill everything at once.
The Live Preview redraws the modal as you type, and the Embed Code panel shows the tag you actually paste. It is one script element that loads popup.min.js from this site and carries only the settings that differ from the defaults, so a plain newsletter popup produces a short tag rather than twenty attributes.
The triggers behave in specific ways. Exit Intent listens for the pointer leaving through the top of the window — a mouseout with no related target above five pixels from the top — so it fires on desktop and never on a touchscreen. Scroll % measures how far down the scrollable height you are and fires once past your figure. Frequency is remembered on the visitor's own device: Once Per Session uses sessionStorage, Once Per Day and Once Forever use localStorage, under a key built from the popup's title.
Limits: the popup is a message with one link, not a form — it cannot collect an email address, and there is no analytics, no A/B test and no per-page targeting, so where the tag is pasted decides where the popup appears. The generator writes code only; nothing is saved here, and the script is served from this site, so an offline copy means hosting popup.min.js yourself.
Use Cases
How to use
Fill in Title, Message, Button Text and Button URL under Content, or click one of the Newsletter, Discount, Dark or Exit Intent presets.
Under Trigger & Behavior pick Timed Delay, Scroll %, Exit Intent or On Page Load, then set the delay or scroll percentage, the Frequency and the animation.
Set Background, Text Color, Button Color and the radius slider, and decide on Overlay Backdrop, Close on Overlay Click and Show branding.
Check the Live Preview, which redraws as you type.
Copy the single script tag from the Embed Code panel and paste it into your page just before the closing body tag.
Check the modal in the Live Preview panel, then press Copy on the Embed Code panel and paste the script tag into your site's HTML.
Pro Tips
- The code only lists settings that differ from the defaults, so a shorter tag does not mean something is missing — a 5-second delay and Once Per Session are simply what the widget already does.
- Exit Intent never fires on a phone: it depends on the mouse pointer leaving the top of the window, and touchscreens have no pointer. Pair it with a scroll or timed popup if mobile matters.
- Frequency is stored per popup title, so changing the Title later gives the widget a new storage key and everyone who had already dismissed the old one will see the new one.
- Untick Show branding and the tag gains data-branding="false", which removes the small Powered by FreeWebTools line under the button.
- The widget also understands data-position="bottom", which the form has no control for — add it to the tag by hand to dock the popup at the bottom of the screen instead of the centre.
Troubleshooting
The popup never appears on my site.
Check three things in order: that the tag was pasted into the page's HTML rather than a text or Markdown field, that your Frequency has not already been satisfied — Once Per Session hides it until the tab is closed — and that the trigger you picked can fire, since Exit Intent needs a mouse.
It works on my computer but not on my phone.
Exit Intent is the usual cause: it depends on the pointer leaving the top of the window, and a touchscreen never generates that event. Switch the trigger to Timed Delay or Scroll % for mobile traffic, or serve a second tag with a different trigger.
I only saw the popup once and now it will not come back.
That is the Frequency working. Once Per Session is remembered in sessionStorage until you close the tab; Once Per Day and Once Forever are remembered in localStorage. Clear the site's storage, or open a private window, to see it again while you are testing.
I changed the design but visitors still see the old popup.
The tag is the popup, so an old tag still on the page keeps its old settings. Replace the whole script element, not just part of it, and clear any page cache or CDN cache afterwards. A stale copy in your own browser cache is worth ruling out too.
Editing the title reset everyone's frequency.
The storage key is derived from the popup's title, so a new title is a new key and nobody's earlier dismissal counts. That is useful when you deliberately want a fresh campaign seen again, and worth remembering when you only meant to fix a typo.
Frequently Asked Questions
One HTML script tag. It points at popup.min.js on this site and carries your settings as data attributes — data-title, data-text, data-btn-text, data-trigger, data-bg and so on — with anything left at its default omitted. Paste that single tag into your page and the popup appears; delete it and the popup is gone.
Copy the tag from the Embed Code panel and paste it into the HTML of the page, just before the closing body tag. In WordPress that means a Custom HTML block or the theme footer; in a static site, the template. No account, no plugin and no build step are involved, because the whole popup is that one script.
Four. Timed Delay waits the number of seconds in the Delay field. Scroll % waits until the visitor has scrolled that far down the page. Exit Intent waits for the pointer to leave through the top of the window. On Page Load shows the popup immediately. The form only shows the Delay or Scroll field that applies.
The script listens for a mouseout event on the document that has no related target and happens within five pixels of the top of the window — the movement of someone heading for the address bar or a browser tab. It fires once per page load. Because it relies on a mouse pointer, it never triggers on a phone or tablet.
That is the Frequency setting. Every Visit shows it on every page load; Once Per Session shows it once until the browser tab is closed; Once Per Day waits 24 hours before showing it again; Once Forever shows it a single time. Once Per Session is the default and is left out of the generated tag.
In the visitor's own browser, not on any server. Once Per Session writes to sessionStorage, and Once Per Day and Once Forever write to localStorage, under a key made from your popup's title. Clearing site data, or opening a private window, resets it and the visitor sees the popup again.
No. The popup shows a heading, a line of text and one button that links to a URL you supply — there is no form field and nothing is submitted anywhere. To capture addresses, point Button URL at a page or a form hosted by your email provider and let that page do the collecting.
Yes, but by placement rather than by a setting. The script runs wherever the tag is, so putting it in a site-wide footer shows it everywhere, while pasting it into one page's HTML limits it to that page. There is no URL rule, no audience targeting and no scheduling in the generator.
The form always centres it, but the underlying widget supports data-position="bottom". Copy the tag, add that attribute by hand, and the modal docks 24 pixels above the bottom edge instead of sitting in the middle. Every other attribute keeps working as generated.
Untick Show branding before you copy. The tag then includes data-branding="false" and the widget skips the small Powered by FreeWebTools link it would otherwise add under the button. Leaving it on costs nothing but a 10-pixel line of grey text.