Voyager’s offer popup is a small, considered conversion surface. It’s intentionally not a generic “10% off!” overlay — it’s framed editorially (“First voyage, fifteen percent.”) and stages the conversion in three deliberate steps that mirror how a fashion-led brand would speak to a first-time visitor. The popup is gated behind a sessionStorage flag, fires once per session on the home page only, and is dismissible at every step.Documentation Index
Fetch the complete documentation index at: https://voyage-theme.fasil.in/llms.txt
Use this file to discover all available pages before exploring further.
When it appears
| Page | Behaviour |
|---|---|
| Home page | Triggers when the visitor has scrolled past the hero (one full viewport height down). Fires once per session. |
| Any other page | Triggers after one viewport of scroll on pages without a hero — but Voyager’s other templates rarely include the popup snippet, so in practice it’s home-only by default. |
overflow is locked to hidden so the popup feels modal.
The three stages
Stage state is stored ondata-step on the container (1, 2, or 3). Each stage has its own slot in the markup; CSS shows/hides them based on data-step.
Stage 1 — persuasion
The first thing the visitor sees. It’s framed as an invitation, not an offer:sessionStorage so the claim is honest.
The primary CTA (“Reveal my 15% code →”) commits the visitor to the small first “yes” — the psychological foot-in-the-door that makes the second-stage email field feel less like a transactional cost.
Stage 2 — capture
Triggered when “Reveal my 15% code →” is clicked.Stage 3 — success
Triggered on form submission.Dismissal mechanics
The popup closes on:| Action | Behaviour |
|---|---|
| × button | Closes, persists voyage-offer-dismissed: true to sessionStorage |
| ”No thanks” link | Same as × button |
| Backdrop click | Same |
| Escape key | Same |
| Stage 3 → Continue browsing | Same (the conversion is already captured) |
voyage-offer-dismissed is true, the popup will not reopen for the rest of the session — even on subsequent page loads, refreshes, or navigation. New session, new opportunity.
The dismissal copy (“15% won’t appear again on this visit”) is honest because of this gate. Don’t loosen it without rewriting the copy.
Performance handling
The popup includes a9:16 video in the media frame. The video file is large (~7.9 MB) and would otherwise drag down the home-page LCP. Voyager handles this with lazy attachment:
- The
<video>element ships withdata-lazy-srcinstead ofsrc - The hidden poster image ships with
data-lazy-srctoo - When the popup opens, JS copies
data-lazy-src→srcand calls.load() - If autoplay doesn’t kick in within 800 ms (iOS Low Power Mode, autoplay block), JS hides the video and shows the poster image instead
Customizing the content
The popup content lives insnippets/offer-popup.liquid. To customize:
| Change | Where |
|---|---|
| Discount % | Update both the stage-1 headline and the stage-3 code display |
| Discount code | Currently ABBARA15 in Stage 3 — replace with your actual code |
| Headline copy | Stage 1 <h2 class="offer-pop__head"> |
| Reassurance line | Stage 2 <p class="offer-pop__reassurance"> |
| Video | Replace assets/popup-video.mp4 (keep data-lazy-src mechanism) |
| Poster image | Replace the Unsplash URL in data-lazy-src on the <img> |
Disabling
The popup ships in the home-page section group viaindex.json. To disable:
- Remove the popup section from your
templates/index.jsoncontent_for_indexarray, or - Remove the
{% render 'offer-popup' %}call from wherever it’s rendered
What’s next
Cart drawer
Where the post-discount add-to-bag lands.
Search panel
The other slide-in surface — same data-open / sessionStorage pattern.