Skip to content

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.

SettingTypeDefaultWhat it does
EnabledCheckboxOffTurns the popup on
Show afterRange8 sHow long after load it appears
VersionText1Change this to show it again to everyone who dismissed it
ImageImage(empty)Optional plate above the copy
KickerTextThe listSmall accent label
HeadingInline rich textThirty minutes' head startRequired — the popup won’t render without it
TextTextList-benefit copy
Show sign-up formCheckboxOnRenders an email sign-up instead of a plain CTA
Customer tagTextpopupThe customer tag applied to sign-ups
PlaceholderTextEmail addressField placeholder
Result buttonTextJoin the listSubmit, or CTA label when the form is off
Button linkURL(empty)Used only when the form is off
Success messageTextYou're on the list.Shown after a successful sign-up
Dismiss labelTextNo thanksThe 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.

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.

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.

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.

  • 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.

  • A real <dialog> opened with showModal(), so focus trapping, Escape and the top layer are the browser’s job rather than reimplemented badly.
  • aria-labelledby points 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.

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.