Rajdip Khavad Logo
Rajdip Khavad
Back to all articles
Engineering

Tracking Customer Behaviour in an Angular SPA with Klaviyo

Rajdip Khavad•2026-09-01•8 min read

# Tracking Customer Behaviour in an Angular SPA with Klaviyo

Customer behaviour tracking in an Angular SPA requires more than sending events from individual components. A useful implementation needs consistent customer identification, meaningful event definitions, rich properties and a safe way to load the tracking provider.

This article uses a hotel booking platform as the example and focuses on practical application architecture.

1. Why Behaviour Tracking Needs an Architecture

A hotel booking application can generate behaviour such as:

📐 Architecture Diagram
Account Created
      ↓
Search Destination
      ↓
View Hotel
      ↓
Save Hotel
      ↓
Checkout Started
      ↓
Booking Confirmed

These actions are useful for lifecycle communication, segmentation and marketing automation.

The challenge is keeping the tracking consistent as the Angular application grows.

2. Centralize Klaviyo Integration

Use an application-level analytics service:

text
Angular Components
       |
       v
AnalyticsService
       |
       v
Klaviyo

The components report business actions. The service owns the Klaviyo integration.

This prevents Klaviyo-specific implementation from being repeated throughout the application.

3. Customer Identification

Customer identification should be established before behaviour events are associated with a customer.

The implementation identifies customers using properties such as:

text
$email
$first_name
$last_name

The analytics layer can therefore establish the customer context and then send subsequent events.

4. Define Behaviour Events

The hotel booking implementation includes:

EventPurpose
Account CreatedNew customer registration
Searched DestinationHotel search activity
No Search FoundSearch returned no useful result
Viewed HotelHotel detail activity
Hotel SavedSaved/favourite hotel
Checkout StartedCheckout initiation
Booking ConfirmedCompleted booking

The event names should represent business behaviour rather than component lifecycle events.

5. Search Behaviour

A search event can contain rich context around the customer's search.

Conceptually:

ts
this.analyticsService.trackKlaviyoSearch({
  destination,
  checkIn,
  checkOut,
  guests
});

The goal is not to send every application property. Instead, send the properties required for meaningful segmentation and automation.

6. No Search Results

A no-result search is a meaningful behaviour signal.

📐 Architecture Diagram
Search
  |
  +---- Results found → Continue browsing
  |
  +---- No results → No Search Found

This can distinguish customers who searched successfully from customers whose destination or criteria did not produce suitable inventory.

7. Hotel Views

Hotel views can capture useful context such as hotel identity and destination.

ts
this.analyticsService.trackHotelView({
  hotelId,
  hotelName
});

This creates a behaviour signal that can later support customer segmentation.

8. Saved Hotels

A saved hotel indicates stronger intent than a simple hotel view.

The Hotel Saved event captures that transition:

📐 Architecture Diagram
Viewed Hotel
     ↓
Saved Hotel
     ↓
Higher booking intent

The exact properties should reflect the information already available in the application at the time of the action.

9. Checkout Started

Checkout initiation is an important lifecycle event:

📐 Architecture Diagram
Hotel
  ↓
Room / option
  ↓
Checkout Started
  ↓
Booking

The event should contain enough booking context to make the activity useful without coupling the marketing platform to the entire application object model.

10. Booking Confirmed

Booking Confirmed represents the completion of the hotel booking journey.

It should be triggered only after the application has established that the booking was successfully completed.

The event can contain booking and hotel context documented by the application's analytics contract.

11. Dynamic Klaviyo Proxy Loading

The implementation uses a dynamic JavaScript proxy/queue in AnalyticsService.ensureKlaviyoProxy().

Conceptually:

📐 Architecture Diagram
Application event
      ↓
AnalyticsService
      ↓
Klaviyo proxy / queue
      ↓
Klaviyo script
      ↓
Klaviyo processing

This allows application code to queue tracking calls while the provider integration becomes available.

The important architectural benefit is that components do not need to manage provider loading themselves.

12. Server-Side Newsletter Subscription

Newsletter subscription is handled differently from browser behaviour events.

The application sends the subscription request to its backend:

📐 Architecture Diagram
Angular
   ↓
Backend API
   ↓
Klaviyo

The backend keeps the private Klaviyo API credential away from the browser.

The implementation uses:

text
POST /User/SubscribeToklaviyo

This separation is important because private API credentials should not be embedded in client-side Angular code.

13. Event Properties Matter

An event name alone provides limited context.

For example:

text
Viewed Hotel

is less useful than:

text
Viewed Hotel
+ hotel identity
+ destination
+ relevant booking/search context

Property design should therefore be intentional and consistent.

14. Avoid Tracking Everything

The goal is not maximum event volume.

A useful event should answer a business question:

  • What did the customer search for?
  • Did they find anything?
  • Which hotel did they view?
  • Did they save a hotel?
  • Did they start checkout?
  • Did they complete the booking?
  • A smaller set of reliable events is generally more useful than a large collection of noisy events.

    15. Keep Business Logic Separate From Klaviyo

    Prefer:

    ts
    this.analyticsService.trackHotelSaved(hotel);

    over direct provider calls from components.

    This keeps Angular components focused on application behaviour and makes provider changes easier later.

    16. Testing the Integration

    Test the lifecycle from the application perspective:

    📐 Architecture Diagram
    Create account
        ↓
    Search
        ↓
    View hotel
        ↓
    Save hotel
        ↓
    Start checkout
        ↓
    Confirm booking

    Validate:

  • customer identification
  • event names
  • event properties
  • event ordering
  • duplicate behaviour
  • provider loading
  • backend subscription handling
  • 17. Common Mistakes

  • Sending events before customer identification.
  • Scattering Klaviyo calls across components.
  • Using inconsistent event names.
  • Sending entire application objects as event properties.
  • Putting private Klaviyo credentials in Angular.
  • Tracking component initialization as customer behaviour.
  • Creating events that have no clear marketing or product purpose.
  • 18. Conclusion

    A reliable Klaviyo integration in an Angular SPA starts with a clear behaviour model and a centralized analytics service.

    For a hotel booking platform, the useful lifecycle is not simply page visits. It is the progression from account creation and search through hotel interest, saved hotels, checkout and confirmed booking.

    A centralized implementation keeps that behaviour consistent while allowing Klaviyo-specific infrastructure to remain isolated from the application's business components.

    Related Content

  • Proven Engineering

    Need enterprise architecture consulting?

    Explore our real-world case studies detailing production migrations, performance scaling, and high-throughput gateways.

    View Case Studies