Back to Playbooks

They Clicked “Download” And Vanished: Fixing Your Lead-Magnet Leak

Free

This playbook shows how to use Spreeflo journeys and custom events to rescue unconsumed lead magnets for Shopify apps, nudging downloaders to actually use your assets and guiding engaged readers toward installs, trials, and meaningful MQLs.

Industry

Niche

Pattern

Loading sequence...

The Shopify merchant is up late on a Sunday, hunting for solutions.

They find your app listing, skim your pitch, and hit a blog post you wrote: “The 7 Flows Adding $10k MRR To Our Customers.” At the bottom you offer a detailed PDF teardown or a Google Sheet calculator. They click “Download now” inside your app or on the web — maybe you even fire a download_started event — and then… nothing.

No PDF open. No scroll depth. No second visit.

From your perspective, that lead magnet might as well not exist.

For an e‑commerce app, that’s painful. Lead magnets are often the bridge between “looks interesting” and “I trust this enough to install.” When someone raises their hand and then drops off before consuming the asset, you’re leaking exactly the kind of intent that should be turning into installs, trial starts, and MQLs.

The sequence at the top of this page is the whole journey, end to end. It’s built for this exact scenario: someone requested your asset, but never actually consumed it. The pattern:

  • Watches for a download_started event

  • Checks if the asset was really opened or completed

  • Re‑delivers it with context if not

  • Pushes engaged downloaders toward your “install app” moment

To make it concrete, we’ll use a fictional app: ConversionForge, a Shopify app helping merchants run A/B tests on product pages. They offer a “High‑Converting Product Page Checklist” PDF and a “Test Ideas” Google Sheet as their main lead magnets. They’re running on Spreeflo’s Professional plan for email plus web tracking, with the Spreeflo SDK installed on their marketing site and in their app.

Let’s walk the journey node by node and see why each one is there — and what happens if you skip it.

Why this seemingly tiny leak matters for an e‑commerce app

If you’re building for Shopify or another e‑commerce platform, you already know where you win:

  • Store owners who are serious enough to research and download resources

  • Merchants who see your app as “the way” to execute what they just learned

  • Trial users who activate and stick, driving LTV in the $1–5k range

Now imagine that every week, 100 people click “Download” on your best asset. Half never actually view it. Those 50 are not just “lost PDF opens,” they’re:

  • Store owners in buying mode who never got your full argument

  • Potential install or trial users who never saw why your app matters

  • People you’ve already qualified by behavior, then silently dropped

Most businesses are leaving lifetime value on the table because they don’t nurture this kind of engagement. It’s not that they don’t care about LTV; they just don’t have a system that turns these micro‑signals into follow‑ups.

The journey you see in the sequence at the top of this page closes that loop. Spreeflo listens to your download_started and download_completed events, waits a sensible amount of time, and then either nudges the contact to finish or escalates them toward your core CTA.

Triggering off real behavior: the Custom Event node

We start the journey with a Custom Event trigger configured for download_started:

  • Type: Custom Event

  • Event name: download_started

  • Re‑enrollment: off (for most setups)

This fires whenever someone requests a download. In ConversionForge’s case, they call Spreeflo.track('download_started', { asset_slug: 'product-page-checklist', source: 'blog_post' }) from their site. That creates a first‑class event in Spreeflo, which you can use not just in journeys but also in the segment builder later.

Why Custom Event and not “Added to Audience” or “Join Segment”?

Because you want this tied to the actual intent signal — that click — not to a softer proxy like “joined newsletter.” The Custom Event trigger gives you precise control, including which asset they chose, where they came from, and more via event properties.

We leave re‑enrollment off so that each contact runs this full journey the first time they request any asset. If you have many different downloads and want a separate pass through the journey per asset, you can make one journey per flagship asset, each with its own download_started trigger and re‑enrollment left on. The important part is: understand Spreeflo’s journey‑level re‑enrollment rules so you don’t accidentally create dead triggers. When in doubt, start with one trigger per journey.

From the trigger, every contact goes straight into a Time Delay.

Giving them a fair shot: Time Delay before checking completion

The first Time Delay node is simple:

  • Type: Time Delay

  • Duration: 1 hour

  • Unit: Hour(s)

You don’t want to fire a “hey, looks like you didn’t open the PDF” email 30 seconds after they click. Many readers download assets to a device, move tabs, or get interrupted.

An hour gives them room to realistically:

  • Open the PDF

  • Skim the content

  • Decide whether to continue or move on

You could choose 4 hours or even a full day depending on your audience and asset type. The key is: wait long enough that “didn’t open” is truly a meaningful signal, not just impatience.

If you skip this node entirely, your follow‑ups will feel robotic and intrusive. For founder‑led apps, that kind of tone mismatch sticks out.

Did they actually consume it? Wait Condition + completion event

After the delay, you want to know whether that asset was opened or completed.

In most app‑side implementations, you can track this with a download_completed or asset_viewed event from your reader or in‑app UI. For ConversionForge, the SDK logs Spreeflo.track('download_completed', { asset_slug: 'product-page-checklist' }) when:

  • The PDF viewer is opened inside the app, or

  • The hosted PDF page loads and scroll passes a threshold, or

  • The Google Sheet link is opened

We capture that in a Wait Condition node:

  • Type: Wait Condition

  • Condition: Custom event “download_completed” triggered at least 1 time in the last 1 day with property asset_slug = the same asset

  • Timeout: 1 day

This does two important jobs:

  1. It gives late openers time to self‑resolve. If they do open the asset, they’ll meet the condition and move down the “completed” branch without your nudge.

  2. It prevents people from hanging indefinitely. After 24 hours, anyone who hasn’t completed falls through to the “did not complete” path.

If you only used a Time Delay here, you’d be blind. You’d treat everyone the same whether they devoured the asset or never opened it. Wait Condition, wired to real custom events via the Spreeflo API, lets you tailor what happens next.

Splitting the path: If/Else for completers vs non‑completers

Once the Wait Condition releases the contact, we insert an If/Else node:

  • Condition: Same “download_completed” criteria as above

  • Then branch: “Completed asset”

  • Else branch: “Did not complete”

Why duplicate the condition we just used in Wait Condition?

Because Wait Condition controls when we move on, not which path we take. There are two scenarios:

  • They completed early: Wait Condition ends as soon as the event occurs, then the If/Else sees the event and routes them to the “completed” path.

  • They never completed: Wait Condition times out after 1 day, then the If/Else sees no event and routes them to the “did not complete” path.

Could you skip the If/Else and put different actions directly after Wait Condition? Not cleanly. You’d have to stuff both behaviors into one node, which the sequence editor doesn’t support. Splitting the logic here is what keeps your journey readable and debuggable.

From here, our two branches behave very differently.

Path A: They completed the asset — move them toward install

For download completers, we don’t need to nag them to open it. We need to help them act on what they just learned and join your app’s core journey.

First, a short Time Delay:

  • Type: Time Delay

  • Duration: 1 day

  • Unit: Day(s)

This gives them space to actually try the ideas in the asset. Then we fire a Send Email node:

  • Type: Send Email

  • Template: “Checklist → Install A/B test app follow‑up”

  • Send only once: on

The content of this email matters more than anything else in the sequence. It should:

  • Reference the specific asset (“You downloaded the High‑Converting Product Page Checklist yesterday.”)

  • Show 1–2 concrete examples of merchants who implemented it, ideally with numbers

  • Tie those examples directly to how your app executes those ideas in one click

  • Offer a clear CTA to install or start trial, plus maybe a secondary CTA to reply with questions

This is where Spreeflo’s email builder comes in. You can set up a clean layout once, then use AI‑generated personalization to drop in lines customized to each merchant’s store type, plan, or region.

Finally, we add an Add Tag node:

  • Tags: asset_completed, plus a more specific asset_completed:product-page-checklist

  • This tag structure lets you later build segments like “Contacts who completed any lead magnet and didn’t install the app yet.” With Spreeflo’s audiences and segments, that becomes an obvious retargeting group for more aggressive offers, webinars, or case studies.

This tag structure lets you later build segments like “Contacts who completed any lead magnet and didn’t install the app yet.” With Spreeflo’s audiences and segments, that becomes an obvious retargeting group for more aggressive offers, webinars, or case studies.

Then this branch ends. They’ve gotten:

  • The asset they asked for

  • Time to use it

  • A clear lift into your core install journey

Path B: They never completed — re‑deliver with context

The “did not complete” branch is where we fix your leak.

Right after the If/Else “else” path, we add a Send Email node:

  • Type: Send Email

  • Template: “Here’s your download (and how to use it in 5 minutes)”

  • Send only once: on

This email is not a generic “hey, you forgot something.” It needs to respect that they were interested enough to click, then got busy. Structure it like this:

  • Subject line that references the asset: “Still want the Product Page Checklist?”

  • First line acknowledging behavior: “You clicked to download the checklist but might not have had time to dive in yet.”

  • A big, immediate direct‑download button or link (no login required if possible)

  • A very short usage guide: “If you’ve only got 5 minutes, do steps 1–3 on your top product page. That alone can move conversion.”

  • A single “If you get stuck, reply to this email with your store URL” line

From a journey design perspective, this is why the node is placed right after the branch. We don’t add another delay here; the one‑day wait already separated real drop‑offs from normal behavior. Any more waiting just lets intent go cold.

After this Send Email, we:

  1. Add Tag: asset_nudge_sent, asset_incomplete

  2. Optional: Send Internal Email to your team if they reply or click repeatedly later (you can use a separate “Email Action” triggered journey for that)

Those tags give you a way to analyze this experiment’s performance:

  • Completion rate after nudge: how many previously incomplete downloaders eventually fire download_completed?

  • Asset‑to‑MQL rate: among those who completed after the nudge, how many start a trial, install the app, or hit whatever MQL definition you encode as a tag or attribute?

Spreeflo’s campaign and journey analytics will show you how many people take each path and where they drop off. That’s how you refine timing, subject lines, and copy over time.

Measuring the right two metrics

You don’t need a complex dashboard for this pattern. Two numbers tell you if it’s pulling its weight.

  1. Completion rate after nudge\nAmong people who triggered download_started but hadn’t completed within the first 24 hours, what percentage fire download_completed after they receive your re‑delivery email?\n\n- If this is under 5%, your asset isn’t compelling enough or your email isn’t clear.\n- If it’s 15–30%, you’ve just recovered a big chunk of otherwise wasted attention.

  2. Asset‑to‑MQL rate\nDefine what “MQL” means for you: maybe it’s app_installed, trial_started, or a custom attribute like is_sales_ready = true. Then track:\n\n- Out of all contacts who completed the asset (whether early or after a nudge), how many become MQLs in the next 7–14 days?\n- Compare that baseline to the group who were nudged — do nudged completers convert at similar rates to first‑time completers?

Because Spreeflo stores all of this behavior on a single contact record, you can build a segment like:

  • Tag contains asset_completed

  • AND event app_installed has not triggered

  • AND Email Activity: opened at least 2 emails in the last 30 days

Then use that segment both in this journey (via an If/Else or Wait Condition) and in future campaigns. You’re systematically nurturing the very people most likely to grow your ARR.

Adapting this for your own Shopify app

The core pattern doesn’t change much across apps:

  • Analytics tools like “ShopMetrics” using dashboard walkthrough PDFs

  • Email/SMS apps offering pre‑built flow libraries as downloads

  • Loyalty or review apps sharing “top‑performing campaign” swipe files

The variations are really about:

  • What you call your custom events (download_started, asset_viewed, guide_completed)

  • How long the first Time Delay and Wait Condition run

  • What “MQL” means in your context

A few guidelines when you adapt:

  • Always trigger from actual behavior, not just schedule. Use Custom Event or Email Action triggers wired to your SDK, not a generic Cyclic blast.

  • Err on the side of fewer, better emails. Two well‑timed emails (nudge + “next step”) beat a 5‑email drip nobody asked for.

  • Use tags and attributes intentionally. Name them so you can build segments you’ll care about six months from now, like asset_nudge_sent, asset_completed:any, asset_type:playbook.

If you haven’t wired in tracking yet, the web tracking and analytics guide walks through adding the SDK and defining custom events. Once that’s set, this journey is an afternoon’s work for a small team — and it runs for you forever.

The bigger play: stop treating engagement as a one‑shot event

Lead magnets for e‑commerce apps are usually treated as top‑of‑funnel content plays. Someone downloads the PDF, maybe joins your list, and then gets dumped into a weekly newsletter no matter what they did next.

This journey takes a different stance:

  • A click is intent, but only if it leads to consumption.

  • Consumption is a moment to add value and earn trust, not just pitch.

  • Both the miss and the hit deserve their own responses.

That’s what nurturing engagement looks like at a practical level. You’re not just measuring “downloads” anymore; you’re designing around who actually got value and who almost did.

For a small, founder‑led Shopify app business, that’s the kind of system that compounds. You build it once, wire it to events you already track, and it quietly converts “curious but busy” store owners into active, engaged trials every week.

If you’re already sending broad campaigns but not listening to what people actually do with your assets, this pattern is a low‑effort, high‑return place to start. Wire up the events, copy the structure from the sequence at the top of this page, and give your best ideas a second chance to be read.