Guides

🪜

Multi-Step Modal Flows

Build a sequence of steps inside a single modal — teasers, email capture, coupon reveals, countdowns, and confirmation screens — all wired to Adobe Target events.

Multi-step mode turns a single popup into a guided flow. Each step can be a different type and navigates independently. Trigger, frequency, and style settings apply to the whole modal — only content varies per step.

💡Common patterns
The most effective flows are 2–3 steps. Popular combinations: Teaser → Email → Confirmation (lead capture), Offer → Coupon reveal (discount delivery), Countdown → Email (urgency-driven capture).

Building a flow — step by step

This walkthrough builds a 3-step teaser → email → confirmation flow. The same steps apply to any combination of step types.

experiencelab.app/modal
ModalBannerCountdown
CONTENT
Multi-step

Steps

Teaser
Email
Confirm
+
CTA ActionNext Step

Navigation

Show back button on this step
STYLING
ThemeDark
BEHAVIOR
TriggerPage Load
Generated Code
1<script>
2(function () {
3 // 3-step modal flow
4 // Teaser→Email→Confirm
5 var KEY = 'el-flow-…';
6 function render() { … }
7})();
8</script>
1

Enable Multi-step mode

Open the Modal tool and expand CONTENT in the left sidebar. Click Multi-step at the top of the CONTENT section — the single-step fields (Headline, Body, CTA) are replaced by a step rail and step editor. Trigger, frequency, and styling settings are unchanged.
2

Add and configure steps

Step 1 is always a Content step. Fill in Headline, Body, and CTA Button Label. Set CTA Action to Next Step. Click + Add to add more steps — switch each to the right type (Email for capture, Confirmation for the final screen). Drag step cards left/right to reorder; hover a card and click × to delete.
3

Add a back button (optional)

In the NAVIGATION section at the bottom of the step editor, check Show back button on this step. Never shown on Step 1 regardless of the checkbox. Only enable it where going back makes sense — not on Confirmation or Coupon steps.
4

Set progress indicator and transition

Expand STYLING. Choose Progress Indicator: Dots (one circle per completed step — best for 2–5 steps), Bar (fills across the top), or None. Choose Step Transition: Slide (directional, native-feeling) or Fade (better when steps differ in length).
5

Name your events

Expand BEHAVIOR. Set Completion Event Name (fires when the visitor finishes the final step — default: modalFlowComplete) and Step View Event Name (fires on each step transition with detail.step and detail.total — default: elStepView). To catch events while testing, paste window.addEventListener('modalFlowComplete', e => console.log(e.detail)) in the console before the script.
6

Generate and test

Click Generate Code → Copy. Open your test page, press F12 → Console, paste and press Enter. Navigate through all steps. Verify transitions and progress indicator. Close mid-flow, re-run — it should reopen at the step you reached (resume). Complete all steps and confirm the completion event fires in the console.

Step types

Content

Headline, body text, and a CTA button. The CTA action can advance to the next step, navigate to a URL, or close the modal. Use as a teaser, offer reveal, or any informational screen.

Email

An email capture form within the flow. On successful submission, it automatically advances to the next step after a brief confirmation moment. No CTA action needed.

💡 Place the email step after a teaser — visitors who see value first are more likely to share their email.

Confirmation

A thank-you or success screen. Typically the last step. CTA action defaults to Close.

💡 Keep the message brief and specific — "You're in! Check your inbox for 20% off" beats "Thank you for subscribing."

Coupon

Displays a prominent coupon code with a one-click copy button. Visitors copy the code without leaving the page.

💡 Pair with urgency copy on the preceding Content step: "Expires tonight" or "First 100 only."

Countdown

Displays a live countdown timer (hours : minutes : seconds). Optional auto-advance: when the timer expires, automatically moves to the next step with no click required.

💡 Use Auto-advance to transition from a countdown into an email capture step — the urgency carries straight into the form.

Image

A full-width image with optional caption and CTA button. Good for product reveals, before/after comparisons, or brand imagery.

Use cases by industry

Real-world flow patterns for five verticals. Pick the one closest to your audience and adapt it.

Flash sale discount delivery

Build anticipation, then deliver the reward.

Click any step to see it in action

Black Friday early access

Be the first to grab 25% off everything.

Why it works: Visitors who click through the teaser are already committed, making the coupon feel earned rather than given.

Cart abandonment recovery

Urgency drives the capture; confirmation keeps the brand warm.

Click any step to see it in action

Your cart is reserved

Items expire in

00 : 14 : 59
HRS · MIN · SEC

Why it works: The countdown primes urgency before the email ask, lifting conversion rates on the form.

New product launch

Tease the reveal, capture the list, confirm the wait.

Click any step to see it in action

Introducing the Aria 2

First 500 buyers get exclusive launch access.

Why it works: Sequenced reveals build anticipation better than a single announcement.

Resume from last step

When a visitor closes the modal mid-flow and returns later, the modal automatically reopens at the step they reached — not step 1. The resume position is stored in localStorage and cleared only when the visitor completes all steps (fires the completion event).

📝To disable resume
Set the frequency to Once per session. A new session always starts at Step 1 — the resume key is scoped per session automatically.

Adobe Target integration

Both events fire as CustomEvent on window. Adobe Tags can listen for them with a Direct Call rule.

Track flow completion as a conversion

Two ways to wire up the conversion — pick whichever fits how the rest of your activity is set up.

1

Add a conversion metric in Adobe Target

In your activity, go to Goals & Settings → Metrics. Add a metric: Goal = Conversion, Action = Clicked an element. In the CSS selector field enter #_atlastcta — the generated script assigns this ID to the final step's CTA button.

A

Adobe Target · Activity

Goals & Settings
XTMulti-Step Modal — Q4 Lead Capture
Experiences·Targeting·● Goals & Settings

Reporting Settings

Goal metric *

My primary goal
Conversion
Clicked an element
i1 element selected#_atlastcta
EditDelete

The Experience Lab script auto-assigns #_atlastcta to the final step's CTA — paste it directly into the element selector. No manual hunting required.

Additional metrics

Configure other success metrics for reporting.

1

Or use Experience Lab's Until Conversion frequency

In Experience Lab's modal builder, open the FREQUENCY section and choose Until conversion. Then in BEHAVIOR, set the Completion Event Name — the script's built-in localStorage suppression handles the rest. The modal re-shows on every visit until the visitor completes the flow, then stops permanently. Adobe Target only deploys the script — no conversion metric, no goal setup, and nothing to wire up on the Target side.

EL

Experience Lab · Modal builder

Sidebar

Frequency

Until conversion

One of nine frequency categories in the dropdown. No extra fields appear when this is selected.

How conversion is detected

  • ·Single-step modal: CTA click marks the visitor converted.
  • ·Multi-step modal: completing the final step fires the Completion Event Name from the BEHAVIOR section, which the script listens for and writes a permanent localStorage flag.
  • ·On every subsequent visit the script reads the flag and returns early — the modal never renders again for that visitor.
💡Want the conversion event in Adobe Analytics or CJA too?
Until Conversion mode handles re-show suppression on its own. To also count completions as a conversion in your analytics platform, listen for the same modalFlowComplete event in an Adobe Tags rule and fire a custom link or XDM payload — the setup is identical to the Step View tracking covered in Step-level analytics below; just swap the rule's identifier from elStepView to modalFlowComplete.

Step-level analytics

Adobe Target reports tell you which whole flow won. To see where visitors drop off mid-flow, capture the elStepView event in your tagging tool and send it to your analytics platform. The event fires on every transition with detail.step (0-based) and detail.total. Pick the implementation below that matches your stack.

Decision · which option fits you

On AppMeasurement (s_code), reporting in AA Workspace

Most legacy stacks. s.tl(), eVars, and props all work as-is.

→ Option A

Migrated to Web SDK (Alloy), still reporting in AA Workspace

The _experience.analytics mapping keeps your existing eVar/prop/event reports alive — no rebuild needed.

→ Option B

Reporting in CJA (with or without AA running alongside)

AEP-native. A custom XDM field group makes step index a first-class CJA dimension — no eVar mapping required.

→ Option C

Hybrid — AA Workspace and CJA, same payload

Combine Option B's _experience.analytics mapping with Option C's custom XDM field group in a single alloy call.

B + C
💡🪄 New: built-in analytics calls in the modal builder
The Modal builder now emits AA s.tl() and/or CJA alloy("sendEvent", …) calls inline — no Adobe Tags rule needed for the basics. Open the ANALYTICS section in the modal sidebar, pick a platform, fill in your slots / tenant, and the generated script ships with tracking baked in. The Tags-rule walkthroughs below are still the right path for teams that want hybrid _experience.analytics mapping or step-level reporting beyond what the built-in shape covers.

Setting it up — step by step

Five clicks from a fresh modal to a fully tracked flow. The mockup on the right updates as you scroll — or click any step to jump.

experiencelab.app/modal
ModalBannerCountdown
Content
Trigger
Frequency
Image
Styling
Behavior
Analytics
Platform
NoneAACJABoth
▼ Generated scriptCopy
1

Open ANALYTICS

In the Modal builder sidebar, scroll past CONTENT / TRIGGER / FREQUENCY / IMAGE / STYLING / BEHAVIOR and expand ANALYTICS. The section is closed by default — opt-in feature, no impact on existing modals.
2

Pick a platform

Choose None (default — no analytics calls emitted), Adobe Analytics (inline s.tl() calls), CJA (inline alloy("sendEvent")), or Both (parallel calls — for hybrid teams running AA Workspace and CJA off the same Web SDK). The fields below appear only after you pick a non-None value.
3

Set Modal Name

Modal Name is the prefix on every event the script emits — e.g. with q4-lead-capture the script fires q4-lead-capture-step-1, q4-lead-capture-cta-2, q4-lead-capture-complete, etc. Auto-defaults to a hyphen-slug of your headline the first time you flip Platform off None — feel free to overwrite.
4

Fill slots / tenant

For Adobe Analytics: enter the eVar slot for the modal step (e.g. eVar10), the event counter slot (event42), and the completion success event slot (event43). For CJA: enter your AEP tenant ID (e.g. citynationalbank). Don't know your tenant? Hit the 🔍 Auto-detect from URL affordance below the field — paste any page on your site that loads Adobe Tags and the server-side detector returns it.
5

Generate and verify

Click Copy on the Generated Script panel and paste into Adobe Target. Inspect the emitted JS — every CTA onclick, step transition, dismiss path, and email submit now contains if(typeof s!=="undefined")… and/or alloy("sendEvent")… guarded calls. To smoke-test live: open your test page, paste the script in DevTools console, click through the modal, and watch the Network tab for /b/ss (AA) or /interact (Web SDK) beacons firing for each event.

What fires when

For a typical 3-step Content → Email → Confirmation flow, here's the exact event sequence the script emits to AA and/or CJA:

What fires when

Event sequence for a 3-step flow (Content → Email → Confirmation)

  1. 1

    Modal opens at Step 1 (Content teaser)

    stepViewstep 1 of 3q4-lead-capture-step-1
  2. 2

    Visitor clicks Step 1 CTA

    ctaClickstep 1 of 3q4-lead-capture-cta-1
  3. 3

    Step 2 (Email capture) renders

    stepViewstep 2 of 3q4-lead-capture-step-2
  4. 4

    Visitor submits the email form

    ctaClickstep 2 of 3q4-lead-capture-cta-2
  5. 5

    Email validated successfully

    emailSubmitq4-lead-capture-email-submit
  6. 6

    Step 3 (Confirmation) renders

    stepViewstep 3 of 3q4-lead-capture-step-3
  7. 7

    Visitor clicks final CTA

    ctaClickstep 3 of 3q4-lead-capture-cta-3
  8. 8

    Flow completes, modal closes

    completeq4-lead-capture-complete
Each event fires both an AA s.tl() call and a CJA alloy("sendEvent") call when Platform = Both. For dismiss events (close button, overlay, Escape) — not shown above — the same pattern applies; a dismissed flow fires q4-lead-capture-dismiss instead of the remaining step / cta / complete events.
💡Scoping matters
Set the Modal Step dimension to Visit-scoped with Most Recent (Last) allocation. Hit-scoped allocation double-counts visitors who close the modal mid-flow and reopen via resume.
📝The eVar / prop / event numbers are placeholders
The examples below use eVar10, prop10, event42, and event43 as illustrative slots. Every Adobe Analytics report suite numbers its own slots independently — substitute whichever eVar / prop / success event positions are free in your environment. Before they capture data, make sure the chosen slots are enabled and named in Admin → Report Suite Settings → Conversion / Traffic / Success Events. Option C (CJA) uses XDM field groups instead of numbered slots, so this only applies to Options A and B.

Option A — AppMeasurement (legacy s_code)

Standard for sites still on AppMeasurement. Build an Adobe Tags rule with Event = Custom Event, identifier = elStepView, then add this Custom Code action.

Adobe Tags — Custom Code action (AppMeasurement)
// Replace eVar10, prop10, event42 with free slots in your report suite.
var stepIndex = event.detail.step;   // 0-based (0 = step 1)
var total     = event.detail.total;
var label     = 'q4-lead-capture-step-' + (stepIndex + 1);

if (typeof s !== 'undefined') {
  s.linkTrackVars = 'prop10,eVar10,events';
  s.prop10 = label;
  s.eVar10 = label;
  s.events = 'event42';                 // counter: modal step viewed
  s.tl(true, 'o', 'Modal Step View');
}

Option B — Web SDK (Alloy)

If you've migrated to Web SDK, replace the s.tl call with alloy("sendEvent", ...). Map the step into legacy Analytics variables under _experience.analytics so existing Workspace reports keep working — same eVar/prop/event numbers as before.

Adobe Tags — Custom Code action (Web SDK / Alloy)
// Replace eVar10, prop10, event42 with free slots in your report suite.
// event1to100 covers events 1–100; use event101to200 / event201to300
// for higher-numbered slots.
var stepIndex = event.detail.step;
var total     = event.detail.total;
var label     = 'q4-lead-capture-step-' + (stepIndex + 1);

alloy("sendEvent", {
  type: "web.webinteraction.linkClicks",
  xdm: {
    eventType: "web.webinteraction.linkClicks",
    web: {
      webInteraction: {
        name: label,
        type: "other",
        linkClicks: { value: 1 }
      }
    },
    // Map to legacy AA variables — keeps existing Workspace reports working
    _experience: {
      analytics: {
        customDimensions: {
          eVars: { eVar10: label },
          props: { prop10: label }
        },
        event1to100: { event42: { value: 1 } }
      }
    }
  }
});

Without writing JavaScript — use the Send Event action

If you prefer the Tags rule UI to writing Custom Code, the setup is three pieces: (1) a Custom Code Data Element that returns the XDM object, (2) a Rule with a Custom Event trigger listening for elStepView on document, and (3) a Send Event action on that rule that fires Alloy with the XDM. Walk-through:

1A

Create a Data Element

Tags · Data Elements · New

The data element holds the XDM payload the action will send. Tags looks up data elements by name, so build this before the rule that references it.

Tags > cnb.com > Data Elements > New

xdm.modalStepView
Core
Custom Code
// `event` is the elStepView CustomEvent on document
var step  = event.detail.step;
var total = event.detail.total;

return {
  eventType: "modalFlow.stepView",
  timestamp: new Date().toISOString(),
  _yourtenant: {
    modalFlow: {
      flowName:   "q4-lead-capture",
      stepIndex:  step,
      totalSteps: total,
      action:     "stepView"
    }
  }
};
next
2A

Create the Rule

Tags · Rules · New

One rule that listens for the modal's elStepView custom event (the trigger) and runs the Send Event action (the payload).

Tags > cnb.com > Rules > New

Modal step view → CJA

IF — when to fire

Events

Core — Custom Event

Type: elStepViewElement: document
Conditions
⊕ Add (none needed)

THEN — what to do

Actions

Adobe Experience Platform Web SDK — Send event

Configured next ↓

next
3A

Configure the Send Event action

Tags · Edit Action

Click the action card from Step 2 to open this form. Reference the data element from Step 1 in the XDM field on the right.

Tags > cnb.com > Rules > Modal step view → CJA > Action Configuration

Adobe Experience Platform Web SDK
Send event
Adobe Experience Platform Web SDK - Send event

Auto-populated from the action type. Leave it as-is or rename for clarity in the rule list.

▸ ADVANCED OPTIONS (collapsed)
alloy

The Web SDK instance name from your extension config. Often alloy (matches the global function) — yours might be different.

Auto-fills or hides certain fields for specific use cases (e.g. page view, link click). Leave unchecked for our custom flow event.

Data

(optional)

Optional override. Skip this — the eventType is already inside the XDM object the data element returns.

xdm.modalStepView

Click the database icon → pick the xdm.modalStepView data element you built in Step 1. This is where Adobe Tags pulls the actual XDM object from.

(optional)

Optional non-XDM payload. Leave empty.

Option C — Customer Journey Analytics (CJA)

CJA reports on AEP datasets, not eVars. Web SDK already lands events in your event dataset — for clean, queryable step data, define a custom XDM field group for modal flows and populate it on every send. This makes step index a first-class dimension in CJA workspaces, no eVar mapping needed.

1

Add a custom XDM field group in AEP

In Experience Platform → Schemas, open your event schema and add a field group _yourtenant.modalFlow with fields: flowName (string), stepIndex (integer, 0-based), totalSteps (integer), and action (string — values: stepView, complete).

2

Send the XDM payload from your Tags rule

Replace yourtenant with your AEP tenant ID. The legacy AA mapping is optional — include it only if you also report in AA Workspace.

3

Build the funnel in CJA

Open a CJA workspace project, drag in the connection, add a Fallout visualization with Modal flow → Step index as the touchpoint dimension. Each value (0, 1, 2…) becomes a step in the funnel automatically.

Here's what the field group looks like in the AEP schema editor once it's saved:

A

Adobe Experience Platform · Schemas

Edit field group

Schema

Web Events Schema

Class

XDM ExperienceEvent

Properties

_yourtenanttenant
modalFlowField group
abcflowNameq4-lead-capture
123stepIndex0-based
123totalStepstotal in flow
abcactionstepView | complete
_experience
web
eventType
timestamp
identityMap

Field group saved · enable on dataset to start collecting

v 1.0

Where to find your AEP Tenant ID

The tenant ID is the short lowercase string Adobe Experience Platform uses to namespace your org's custom XDM fields — it's the prefix in paths like _yourtenant.modalFlow.stepIndex. It's typically a shortened version of your company name (e.g. acmecorp, cnb, cjmcybs). It is not the IMS Org ID, the Dataset ID, the sandbox name, or the Datastream ID.

1

Open AEP → Schemas → Browse

Click any custom field group your team has created. In the schema field tree, expand any group — paths starting with _yourtenant.something reveal the prefix. The string between the leading _ and the first . is your Tenant ID.

2

Or check the AEP Web SDK extension config in Tags

Adobe Tags → your property → Extensions → Adobe Experience Platform Web SDK → Configure. The configured XDM data element type or the Datastream config often surfaces the tenant prefix.

3

Or fire a test alloy() call and inspect the network beacon

On a page where Web SDK is already loaded, run alloy("sendEvent", { xdm: { eventType: "test" } }); in the console. Open the Network tab, find the /interact request, expand the payload — the tenant prefix appears in the XDM path.

4

Or just ask your data engineering team

If you don't have direct AEP UI access, the team that owns your Adobe Experience Platform implementation can answer in 30 seconds. Tell them: "I need our AEP Tenant ID for an XDM custom field group."

5

Or use the auto-detect tool in the modal builder

The modal builder's ANALYTICS section has a Auto-detect from URL affordance — paste any page on your site that has Adobe Tags loaded, and it'll fetch the Tags container and extract the tenant prefix automatically.

📝Other Adobe IDs you might confuse with the tenant ID
While inspecting your Adobe setup you'll see several identifiers that look related but are different things — none of these go in the AEP Tenant ID field:
  • IMS Org ID — long format like 2DD68785558BD0AB7F000101@AdobeOrg. Identifies your Adobe org globally; used in API auth and SDK init. Sometimes the tenant prefix is a transliteration of the company name in this org, but the IDs themselves are independent.
  • Datastream Config ID — UUID like 691e8bad-1502-4169-896d-bb5538df3261. Identifies which datastream your Web SDK forwards data through. Visible in the configId query param of every /interact call.
  • Edge endpoint hostname — sites with first-party CNAMEs route Web SDK traffic through their own domain (e.g. smetrics.yoursite.com/ee/v1/interact) instead of edge.adobedc.net. This is a delivery detail — has no bearing on the tenant.
  • Sandbox name — typically prod, dev, or stage. Identifies which AEP environment your data lands in. Each sandbox has its own datasets and schemas, but they share the same tenant prefix across the org.
Adobe Tags — Custom Code action (CJA via Web SDK + custom XDM)
alloy("sendEvent", {
  xdm: {
    eventType: "modalFlow.stepView",
    timestamp: new Date().toISOString(),
    web: {
      webPageDetails: {
        URL:  window.location.href,
        name: document.title
      }
    },
    _yourtenant: {
      modalFlow: {
        flowName:   "q4-lead-capture",
        stepIndex:  event.detail.step,    // 0-based
        totalSteps: event.detail.total,
        action:     "stepView"
      }
    }
  }
});

Build the funnel in Workspace

Same setup whether you're in Adobe Analytics Workspace or CJA — only the dimension source differs.

1

Drag in a Fallout visualization

From the Visualizations panel of a new project. Workspace also accepts a fallout from a freeform table — use whichever you prefer.

2

Set the Touchpoint dimension

AA Workspace: whichever eVar you populated above (e.g. eVar10 — substitute your own slot). CJA: your custom Modal flow → Step index XDM dimension.

3

Drop one filter per step

AA: drop the eVar value for each step (q4-lead-capture-step-1, …-step-2, …-step-3). CJA: drop stepIndex = 0, 1, 2.

4

Add a converter segment (optional but powerful)

Filter the fallout on the completion success event (e.g. event43 — substitute your own slot) in AA, or action = complete in CJA) to compare paths of converters vs. abandoners side-by-side.

5

Read the curve

Each bar shows the conversion rate from one step to the next. Steep drops at Step 2 usually mean friction in the email field. Drops at the final step usually mean weak CTA copy or an unclear value reveal. This becomes an actionable report — every drop-off point is a hypothesis the Adobe Target team can test next: shorter copy at Step 1, fewer fields on the email step, a stronger value reveal before the final CTA. Run those as A/B activities against the same funnel and each iteration compounds the lift.

🪜 Need help wiring up a multi-step flow end to end?

Experience Lab can design the step sequence, configure Adobe Target conversion tracking, and set up Adobe Analytics funnel reporting — so you can measure every step of your flow from day one.

Get in touch