User Journey Tracker Service (UserJourneyTrackerService) β
Overview β
The UserJourneyTrackerService is the primary interface for capturing a detailed, chronological record of a user's session (the "Journey").
It manages the session lifecycle, automatically collects context data (device, URL, assignments), and batches events for efficient data transmission.
The service's API is designed for semantic tracking, providing specialized methods for distinct event categories (e.g., interactions, form changes, navigation, and conversions) to minimize noise and maximize analytical value.
Core Event Structures β
JourneyEvent(generated by most methods): Used for general activity and milestones. Automatically enriched with context (URL, device, timestamps, etc.).ConversionEvent(viatrackConversionEvent): Specialized event with mandatory fields (testId,variantId,metricId) required for A/B test analysis.
1. Core Concepts and Session Management β
- User Journey: A continuous session that begins when a user is identified (via
startJourney). It serves as the container for all subsequent events. - Session Management:
- Inactivity and maximum session duration are automatically managed (e.g., 30 minutes of inactivity).
- Activity is tracked via mouse movements, clicks, and focus changes.
- Contextualization: Every event is automatically enriched with contextual data (current URL, viewport size, device type, active A/B test assignments).
1.1 Journey and Session Control API β
| Method | Description | Arguments | Best Use Case |
|---|---|---|---|
startJourney(journeyName: string, config?: UserJourneyConfig) | Initializes and tracks the start of a logical user session. Resets timers and attaches a unique Session ID to all subsequent events. | - journeyName (string): Unique ID (e.g., application_session, onboarding). - config (optional): Overrides session defaults (timeouts, etc.). | Called once when a user is identified or starts a major application flow. |
endJourney(properties?: Record<string, unknown>) | Manually signals the end of the current journey by sending a journey_completed event. | - properties (optional): Any final context to attach to the completion event. | Use for explicit completion points (purchase, sign-out, exit from a major flow). |
2. Granular Event Tracking (Generating JourneyEvent) β
These methods track specific user actions and state changes that are not related to A/B test conversion or funnel steps.
2.1 API Reference: Granular Methods β
| Method | Description | Arguments | Event Type |
|---|---|---|---|
trackJourneyEvent(name: string, props?: Record<string, unknown>) | General-purpose tracking method for any milestone or event not covered by specialized trackers. | - name (string): Semantic name (e.g., data_sync_complete). - props (optional): Custom data. | generic_event |
trackUserInteraction(name: string, props?: Record<string, unknown>) | Tracks direct user interaction with UI elements (clicks, gestures, hovers). | - name (string): Interaction type (e.g., button_click, drag_gesture). - props (optional): Element details (e.g., elementId, position). | user_interaction |
trackFormInteraction(formId: string, name: string, props?: Record<string, unknown>) | Tracks progress and outcomes within a specific form or transactional process. | - formId (string): Unique form name (e.g., signup_form). - name (string): Status (e.g., start, field_error, submit_success). | form_interaction |
2.2 Granular Tracking Example β
// Example of specific tracking in a component
import { Component, inject } from '@angular/core';
import { UserJourneyTrackerService } from '.../user-journey-tracker.service';
@Component({...})
export class SettingsComponent {
private tracker = inject(UserJourneyTrackerService);
onProfileSave(isSuccess: boolean): void {
if (isSuccess) {
// Track a successful form submission
this.tracker.trackFormInteraction('profile_settings_form', 'submit_success', {
profileType: 'premium',
timeTaken: 500 // ms
});
// Track a generic high-value milestone
this.tracker.trackJourneyEvent('user_profile_updated', {
settingGroup: 'core_info'
});
} else {
// Track a failure interaction
this.tracker.trackFormInteraction('profile_settings_form', 'submit_failure', {
errorReason: 'Email invalid',
fieldInError: 'email'
});
}
}
onFilterApplied(filterKey: string): void {
// Track a click/action interaction
this.tracker.trackUserInteraction('filter_applied_click', {
elementId: `filter-${filterKey}`,
value: 'active',
});
}
}3. Navigation and Page View Tracking β
3.1 API Reference: Navigation Methods β
| Method | Description | Arguments | Best Use Case |
|---|---|---|---|
trackPageView(page: string, props?: Record<string, unknown>) | Records that a page or route has finished loading and is being viewed. | - page (string): Page/route name (e.g., /product/123). - props (optional): Contextual data (e.g., referrer). | Best practice: Handled globally by subscribing to Angular Router events. |
trackPageNavigation(destination: string, type: 'link' | 'button' | 'back', props?: Record<string, unknown>) | Tracks explicit user action that initiated navigation. | - destination (string): Target route or URL. - type (string): Mechanism used (link, button, back, forward). | Use in components to link navigation action to page change. |
3.2 Navigation Tracking Example (Global Router Hook) β
import { Component, inject } from '@angular/core';
import { Router, NavigationEnd } from '@angular/router';
import { filter } from 'rxjs/operators';
import { UserJourneyTrackerService } from '.../user-journey-tracker.service';
@Component({...})
export class AppComponent {
private router = inject(Router);
private tracker = inject(UserJourneyTrackerService);
constructor() {
// 1. Global Page View Tracking
this.router.events.pipe(
filter(event => event instanceof NavigationEnd)
).subscribe((event: NavigationEnd) => {
this.tracker.trackPageView(event.urlAfterRedirects, {
isInitialLoad: this.router.navigated ? false : true
});
});
}
// 2. Manual Navigation Tracking
onCustomNavigation(route: string): void {
this.tracker.trackPageNavigation(route, 'button', {
sourceComponent: 'sidebar_menu'
});
this.router.navigateByUrl(route);
}
}4. Goal, Funnel, and A/B Test Tracking β
4.1 API Reference: Goal and Funnel Methods β
| Method | Description | Arguments | Recommended Use Case |
|---|---|---|---|
trackFunnelStep(funnelId: string, stepName: string, properties?: Record<string, unknown>) | Tracks successful progress through a multi-step process. | - funnelId (string): Funnel name. - stepName (string): Must follow x-identifier. | Analyze drop-off and time-to-completion in sequential flows (e.g., checkout). |
trackFunnelDropoff(funnelId: string, stepName: string, reason: string, properties?: Record<string, unknown>) | Marks the point where a user exited a funnel prematurely. | - funnelId (string): Funnel name. - stepName (string): Step before exit. - reason (string): Cause (e.g., cancelled, payment_failure). | Calculate dropoff rates and identify abandonment causes. |
trackConversionEvent(event: ConversionEvent) | Tracks an A/B test Success Metric. | - event (ConversionEvent): Must include metricId, testId, variantId, and value. | Used exclusively for A/B test analysis. |
4.2 Funnel Naming Convention (MANDATORY) β
The stepName must follow the format:
x-identifierThis ensures chronological ordering and clear branching in analytics.
Sequential Steps:
1-initiate2-task-overview-reached3-created-new-task
Branching Paths:
2.1-task-overview-reached2.2-task-overview-skipped
4.3 Goal Tracking Examples β
// Example of tracking funnel progression, dropoff, and AB conversion
@Injectable({ providedIn: 'root' })
export class CheckoutService {
private tracker = inject(UserJourneyTrackerService);
private checkoutFunnelId = 'standard_checkout_flow';
/**
* Tracks progression through the funnel.
* Called on successful move to the next step.
*/
proceedToShipping(): void {
this.tracker.trackFunnelStep(this.checkoutFunnelId, '1-cart-review-complete');
// ... navigate to shipping page
}
/**
* Tracks a drop-off from the funnel.
*/
handleDropoff(stepName: string, reason: string): void {
this.tracker.trackFunnelDropoff(
this.checkoutFunnelId,
stepName, // e.g., '2-shipping-details-page'
reason, // e.g., 'high_shipping_cost'
{ cartTotal: 150.99 },
);
}
/**
* Tracks a final purchase as a Conversion Event for an A/B test.
*/
completePurchase(testId: string, revenue: number, assignedVariant: VariantType): void {
const purchaseEvent: ConversionEvent = {
timestamp: new Date(),
testId: testId,
metricId: 'purchase_conversion',
variantId: assignedVariant,
value: revenue,
properties: {
orderId: 'O-12345',
currency: 'USD',
},
};
this.tracker.trackConversionEvent(purchaseEvent);
}
}