Flow Events Tracking
Track the right flow events to gain actionable insights without noise.
Overview#
Event tracking in flows serves two purposes:
- Funnel analysis: Understand where users drop off in multi-step flows
- Behavior insights: Learn what users engage with and what they skip
The key is balance — track enough to understand behavior, but not so much that you drown in noise.
System Events (Automatic)#
The SDK automatically tracks flow lifecycle at the native layer, outside of your flow code. These events fire regardless of what your flow does:
| Event | When | Insight |
|---|---|---|
__started__ | Flow is presented (before any flow JS runs) | How many users see the flow |
__completed__ | complete() is called | How many users finish successfully |
__dismissed__ | dismiss() is called | How many users exit early |
With just these three events, you get a basic conversion rate: __completed__ / __started__
Don't track events that duplicate system events under different names (e.g., flow_started, paywall_viewed, flow_dismissed). The SDK already handles this. Event names starting with __ are reserved.
What to Track#
✓ Track Committed Decisions#
// ✓ GOOD: Committed decisions — user moves forward
// Step completion - shows funnel progression
Mobana.trackEvent('step_1_completed');
Mobana.trackEvent('step_2_completed');
Mobana.trackEvent('step_3_completed');
// Confirmed choices - user committed and proceeded
Mobana.trackEvent('plan_confirmed'); // Tapped Continue after picking a plan
Mobana.trackEvent('interests_confirmed'); // Submitted selected interests
Mobana.trackEvent('theme_set'); // Confirmed theme choice
// Permission outcomes
Mobana.trackEvent('notification_granted'); // System granted permission
Mobana.trackEvent('notification_denied'); // System denied permission
// Deliberate exits
Mobana.trackEvent('onboarding_skipped'); // User chose to skip✗ Avoid These#
// ✗ BAD: Noise-generating events
// Don't track cyclical/toggleable interactions — creates loops in journey diagrams
Mobana.trackEvent('plan_tapped'); // User taps between plans before deciding
Mobana.trackEvent('toggle_switched'); // User toggles monthly/annual back and forth
Mobana.trackEvent('tab_changed'); // User browses tabs — not a decision
// Don't duplicate system events under different names
Mobana.trackEvent('flow_started'); // __started__ already covers this
Mobana.trackEvent('paywall_viewed'); // __started__ already covers this
Mobana.trackEvent('flow_dismissed'); // __dismissed__ already covers this
// Don't track micro-interactions
Mobana.trackEvent('button_hovered'); // Not actionable
Mobana.trackEvent('scroll_started'); // Not actionable
// Don't use vague names
Mobana.trackEvent('click'); // Click on what?
Mobana.trackEvent('action'); // What action?The Golden Rule#
"If this event count changes, would I change the flow?"
If not, you probably don't need the event.
- step_2_completed increases: "Great, step 2 is working well. Maybe optimize step 3 now."
- plan_confirmed drops: "Users are browsing plans but not committing — simplify the pricing step."
- plan_tapped increases: "...so what? They're just browsing." (Don't track this)
Funnel Tracking Pattern#
For multi-step flows, track completion of each step to identify drop-off points:
// ONBOARDING FLOW - Event Strategy
// These events create a clear funnel in analytics:
// __started__ (automatic) → step_1 → step_2 → step_3 → __completed__
document.getElementById('step-1-continue').addEventListener('click', () => {
Mobana.trackEvent('step_1_completed'); // 1. Track step
Mobana.haptic('light');
showStep(2);
});
document.getElementById('step-2-continue').addEventListener('click', () => {
Mobana.trackEvent('step_2_completed'); // 2. Track step
Mobana.haptic('light');
showStep(3);
});
document.getElementById('step-3-finish').addEventListener('click', () => {
Mobana.trackEvent('step_3_completed'); // 3. Track step
Mobana.haptic('success');
Mobana.complete({ onboardingVersion: '2.0' }); // → triggers __completed__
});
// Track skip/dismiss too - valuable insight
document.getElementById('skip-btn').addEventListener('click', () => {
Mobana.trackEvent('onboarding_skipped');
Mobana.dismiss(); // → triggers __dismissed__
});This creates a funnel in your Dashboard:
Tracking Committed Decisions#
Track the moment a user commits to a choice and moves forward — not every exploratory tap:
// DECISION POINTS - Track when the user commits, not when they browse
// Plan selection — track on the Continue button, not on each plan tap
// (user may tap between plans multiple times before deciding)
document.getElementById('continue-btn').addEventListener('click', () => {
const plan = document.querySelector('input[name="plan"]:checked').value;
Mobana.trackEvent('plan_confirmed');
Mobana.complete({ plan });
});
// Interests/preferences — track the submission, not each toggle
document.getElementById('confirm-interests').addEventListener('click', () => {
const selected = getSelectedInterests();
Mobana.trackEvent('interests_confirmed');
showNextStep();
});
// Permission decisions — track the outcome
document.getElementById('enable-notifications').addEventListener('click', async () => {
const granted = await Mobana.requestNotificationPermission();
Mobana.trackEvent(granted ? 'notification_granted' : 'notification_denied');
showNextStep();
});
// Deliberate skip
document.getElementById('skip-btn').addEventListener('click', () => {
Mobana.trackEvent('onboarding_skipped');
Mobana.dismiss();
});Naming Convention#
Consistent naming makes analytics easier to understand:
// NAMING CONVENTION
// Use snake_case
Mobana.trackEvent('step_completed'); // ✓ Good
Mobana.trackEvent('stepCompleted'); // ✗ camelCase
Mobana.trackEvent('StepCompleted'); // ✗ PascalCase
Mobana.trackEvent('step-completed'); // ✗ kebab-case
// Be specific
Mobana.trackEvent('notification_granted'); // ✓ Clear
Mobana.trackEvent('click'); // ✗ Click on what?
// Use consistent prefixes
Mobana.trackEvent('step_1_completed');
Mobana.trackEvent('step_2_completed');
Mobana.trackEvent('step_3_completed');
// Include context
Mobana.trackEvent('plan_confirmed');
Mobana.trackEvent('upgrade_declined');
Mobana.trackEvent('onboarding_skipped');Recommended Events by Flow Type#
Onboarding Flow#
- • step_1_completed, step_2_completed, step_3_completed
- • interests_confirmed (if collecting preferences)
- • onboarding_skipped (if they skip)
Permission Flow#
- • notification_granted / notification_denied
- • att_authorized / att_denied
Upsell/Upgrade Flow#
- • plan_confirmed (with plan name in completion data)
- • upgrade_accepted / upgrade_declined
Survey/Feedback Flow#
- • question_1_answered, question_2_answered, etc.
- • rating_submitted (with rating value in completion data)
- • feedback_submitted
Post-Flow Event Tracking#
Track events after the flow closes using the result's trackEvent function:
// In your app
const result = await Mobana.startFlow('pre-purchase');
if (result.completed) {
// User completed the flow, now watch for purchase...
// Later, when purchase happens:
await result.trackEvent?.('purchase_completed', { amount: 49.99 });
// Or use trackConversion with sessionId for attribution
Mobana.trackConversion('purchase', 49.99, result.sessionId);
}