Promo popup
A dialog that appears after a delay you set, carrying either a sign-up form or a call to action. Off by default, and never shown twice to the same person unless you say so.
Settings
Section titled “Settings”| Setting | Type | Default | What it does |
|---|---|---|---|
| Enabled | Checkbox | Off | Turns the popup on |
| Show after | Range | 8 s | How long after load it appears |
| Version | Text | 1 | Change this to show it again to everyone who dismissed it |
| Image | Image | (empty) | Optional plate above the copy |
| Kicker | Text | The list | Small accent label |
| Heading | Inline rich text | Thirty minutes' head start | Required — the popup won’t render without it |
| Text | Text | List-benefit copy | |
| Show sign-up form | Checkbox | On | Renders an email sign-up instead of a plain CTA |
| Customer tag | Text | popup | The customer tag applied to sign-ups |
| Placeholder | Text | Email address | Field placeholder |
| Result button | Text | Join the list | Submit, or CTA label when the form is off |
| Button link | URL | (empty) | Used only when the form is off |
| Success message | Text | You're on the list. | Shown after a successful sign-up |
| Dismiss label | Text | No thanks | The decline control |
Two modes: with show_form on it’s a sign-up and submissions arrive as customers tagged with your tag value. With it off, button_label and button_link make it a plain announcement with a CTA.
The version key is the useful part
Section titled “The version key is the useful part”When a shopper dismisses the popup, their browser remembers it — under a name that includes whatever you typed in Version. On their next visit the popup looks for that same name, finds it, and stays hidden.
Change the version and the name changes with it, so nothing matches and everyone counts as new again.
That’s what lets you run a new promo without every returning shopper being excluded by a dismissal from the last one. Change the copy, change Version from 1 to 2, and the popup is offered again to everyone — including people who closed the previous one.
Two things follow from this:
- It’s remembered per browser, per device. The same person sees it again on their phone, and again in a private window. No theme can do better; tying a dismissal to a customer requires an app.
- Any change resets everyone. A typo you correct counts as a new version. Harmless, but a stray keystroke re-shows the popup to your whole audience.
The value doesn’t have to be a number — spring-drop works as well as 2. It only has to differ from last time.
Timing
Section titled “Timing”The delay is deliberate and should stay non-zero. It means the popup cannot interrupt the first paint, can’t fight the loading overlay, and gives a visitor a moment to see what the store is before being asked for their address. Eight seconds is the default.
It always shows in the theme editor
Section titled “It always shows in the theme editor”Dismissal is ignored in design mode — otherwise you could configure it once, dismiss it, and never be able to preview it again. On the storefront the dismissal is respected normally.
Dismissal
Section titled “Dismissal”- The × closes it and remembers.
- Escape closes it — the browser’s own
<dialog>behaviour — and remembers. - Clicking the backdrop closes it and remembers.
- The CTA link also carries the dismiss behaviour, so a shopper who clicks through isn’t asked again.
Every one of those paths records the dismissal, so there’s no route that closes the popup and leaves it able to return on the next page.
Accessibility
Section titled “Accessibility”- A real
<dialog>opened withshowModal(), so focus trapping, Escape and the top layer are the browser’s job rather than reimplemented badly. aria-labelledbypoints at the heading.- The email field has a visually hidden label as well as a placeholder, and
autocomplete="email". - The success message is
role="status", so it’s announced. - Page scroll is locked while open and released on close.
Rendered from the layout
Section titled “Rendered from the layout”Like the age gate, the popup is rendered from the theme layout rather than a template — a promo a shopper never reaches is no promo, and most shoppers don’t land on the homepage. It stays editable in the theme editor.