Heap Event Tracking | Blue Frog Docs

Heap Event Tracking

Complete guide to Heap event tracking and measurement

Heap Event Tracking

Overview

Heap takes a fundamentally different approach to analytics: automatic event capture. Instead of manually instrumenting every interaction you want to track, Heap's JavaScript snippet automatically captures all user interactions - clicks, form submissions, page views, and more - without requiring code changes.

This "retroactive analytics" model means you can define events after data collection has started. Click on a button in Heap's visual interface, give it a name, and instantly see historical data for that interaction. This makes Heap particularly appealing for teams that want comprehensive data without extensive developer involvement.

Event Model

How Heap Events Work

Heap captures two types of data:

  1. Pageviews: Automatically tracked on every page load
  2. Events: All user interactions (clicks, form submissions, changes)

Unlike traditional analytics platforms, you don't send events via code. Heap's snippet captures everything, and you define what matters in the Heap interface retroactively.

Automatic Capture Includes:

  • All clicks on any element
  • All form submissions
  • All input changes
  • All page views
  • Touch events (mobile)
  • Text selections

Event Structure (Post-Definition):

{
  "event_type": "Button Clicked - CTA Homepage",
  "time": 1640995200000,
  "user_id": "user_12345",
  "session_id": "session_abc123",
  "properties": {
    "page_url": "https://example.com/",
    "target_text": "Sign Up Free",
    "target_class": "btn-primary",
    "referrer": "https://google.com"
  }
}

Key Concepts

  • Autocapture: Heap records all interactions automatically
  • Retroactive Events: Define events after data is collected
  • Visual Labeling: Click elements in the UI to create events
  • Sessions: Grouped sequences of user activity
  • User Properties: Custom attributes set via API
  • Event Properties: Automatically captured element attributes

Limits

  • Event definitions: Unlimited
  • User properties: 500 per user
  • Session properties: Unlimited
  • Custom events (via API): Unlimited
  • Data retention: Based on plan (6-24+ months)

Standard Events

Heap automatically captures standard web interactions out of the box.

Automatically Captured Events

Pageviews:

  • Fires on every page load
  • Includes URL, title, referrer
  • Can segment by page properties

Clicks:

  • Every clickable element
  • Buttons, links, images, divs
  • Includes target text, classes, IDs

Form Interactions:

  • Form submissions
  • Input changes
  • Focus events

Touch Events (Mobile):

  • Taps
  • Swipes
  • Gestures

Viewing Autocaptured Data

In Heap interface:

  1. Go to Define > Events
  2. Click "Create Event"
  3. Choose "Click" or "Form Submission"
  4. Click the element on your site
  5. Name the event
  6. Save - now you have historical data

Example: Defining a Click Event

Without code, in Heap UI:

  1. Navigate to your homepage
  2. Click the CTA button
  3. Name it: "CTA - Homepage Sign Up"
  4. Add filters (optional):
    • Target text contains "Sign Up"
    • Page URL contains "/homepage"
  5. Save - instant historical analytics

Custom Events

While Heap autocaptures interactions, you'll want to track some events manually (server-side actions, custom logic, business events).

Track API (Custom Events)

JavaScript:

// Basic custom event
heap.track('Video Played', {
  'video_title': 'Product Demo',
  'video_duration': 180,
  'video_quality': '1080p'
});

// Event with multiple properties
heap.track('Purchase Completed', {
  'order_id': 'ORDER_12345',
  'revenue': 149.99,
  'product_count': 3,
  'payment_method': 'credit_card',
  'shipping_method': 'standard'
});

// Track complex events
heap.track('Feature Enabled', {
  'feature_name': 'Dark Mode',
  'enabled_from': 'settings',
  'user_tier': 'premium'
});

When to Use Custom Events

Use heap.track() for:

  • Server-side events: Backend processes, API calls
  • Business logic events: Calculations, validations
  • Third-party integrations: Payment processed, email sent
  • Events without DOM interactions: Timers, background tasks
  • Mobile app events: iOS/Android specific actions

Custom Event Best Practices

✅ Do:

  • Use for events that can't be autocaptured
  • Name events clearly: "Subscription Upgraded"
  • Include relevant properties
  • Track both success and failure states

❌ Don't:

  • Track clicks/pageviews (already autocaptured)
  • Duplicate autocaptured events
  • Send events for every function call
  • Include PII without hashing

Ecommerce Events

Heap handles ecommerce through a combination of autocapture and custom events.

Product Browsing (Autocaptured)

Product Clicks:

  • Define in Heap UI by clicking product cards
  • Automatic properties: target text, href, classes
  • Can filter by page URL pattern

Category Navigation:

  • Autocaptured link clicks
  • Label in UI: "Category - Electronics Clicked"

Cart Actions (Custom Events)

// Add to cart
heap.track('Product Added to Cart', {
  'product_id': 'SKU_12345',
  'product_name': 'Wireless Headphones',
  'price': 199.99,
  'quantity': 1,
  'category': 'Electronics',
  'cart_total': 199.99,
  'cart_items': 1
});

// Remove from cart
heap.track('Product Removed from Cart', {
  'product_id': 'SKU_12345',
  'cart_total': 0,
  'removal_reason': 'price'
});

// Update quantity
heap.track('Cart Quantity Updated', {
  'product_id': 'SKU_12345',
  'old_quantity': 1,
  'new_quantity': 2,
  'cart_total': 399.98
});

Checkout Flow

// Checkout started
heap.track('Checkout Started', {
  'cart_total': 399.98,
  'item_count': 2,
  'checkout_type': 'guest'
});

// Shipping info added
heap.track('Shipping Info Added', {
  'shipping_method': 'express',
  'shipping_cost': 15.00,
  'estimated_days': 2
});

// Payment info added
heap.track('Payment Info Added', {
  'payment_method': 'credit_card'
});

// Purchase completed
heap.track('Order Completed', {
  'order_id': 'ORDER_12345',
  'revenue': 414.98,
  'subtotal': 399.98,
  'tax': 32.00,
  'shipping': 15.00,
  'discount': 32.00,
  'coupon_code': 'SAVE10',
  'item_count': 2,
  'payment_method': 'credit_card',
  'is_first_purchase': true
});

Revenue Tracking

Heap has built-in revenue analysis when you include revenue property:

heap.track('Purchase', {
  'revenue': 414.98, // Required for revenue reports
  'order_id': 'ORDER_12345',
  'currency': 'USD'
});

User Properties

User properties describe attributes of the user. In Heap, these are called "User Properties" and must be set via API.

Setting User Properties

JavaScript:

// Identify user (required before setting properties)
heap.identify('user_12345');

// Add user properties
heap.addUserProperties({
  'email': 'john@example.com',
  'name': 'John Doe',
  'plan': 'Premium',
  'signup_date': '2024-01-15',
  'account_age_days': 45,
  'total_purchases': 3,
  'lifetime_value': 449.97
});

// Update single property
heap.addUserProperties({
  'last_login': new Date().toISOString()
});

User Property Operations

Heap's user properties are additive (last write wins):

// Initial properties
heap.addUserProperties({
  'plan': 'Basic',
  'login_count': 1
});

// Update properties
heap.addUserProperties({
  'plan': 'Premium', // Overwrites
  'login_count': 2   // Overwrites (use custom logic to increment)
});

Standard User Properties

Common user properties to track:

heap.addUserProperties({
  // Identity
  'email': 'user@example.com',
  'name': 'John Doe',
  'user_id': 'user_12345',

  // Account
  'signup_date': '2024-01-15',
  'account_tier': 'Premium',
  'subscription_status': 'active',

  // Engagement
  'total_logins': 42,
  'last_active': new Date().toISOString(),
  'favorite_feature': 'dashboard',

  // Business
  'company_name': 'Acme Corp',
  'industry': 'Technology',
  'employee_count': '50-100',

  // Behavioral
  'total_purchases': 3,
  'lifetime_value': 449.97,
  'preferred_category': 'Electronics'
});

Removing User Properties

Heap doesn't support removing properties, but you can set to null:

heap.addUserProperties({
  'temporary_flag': null
});

Event Properties

Event properties in Heap come from two sources: autocaptured element attributes and custom properties you pass to heap.track().

Autocaptured Properties

Every autocaptured event includes:

Page Properties:

  • Page URL: Current page URL
  • Page title: Document title
  • Referrer: Previous page
  • Query parameters: URL params

Element Properties:

  • Target text: Button/link text
  • Target href: Link destination
  • Target id: Element ID
  • Target class: CSS classes
  • Target tag: HTML tag (button, a, div)
  • Target attributes: Data attributes

Session Properties:

  • Browser: Browser name/version
  • Device type: Desktop, mobile, tablet
  • OS: Operating system
  • Screen size: Resolution
  • UTM parameters: Campaign tracking

User Properties:

  • User ID: If identified
  • Session ID: Current session
  • All custom user properties

Custom Event Properties

When using heap.track():

heap.track('Video Engagement', {
  // Content properties
  'video_id': 'vid_12345',
  'video_title': 'Product Tutorial',
  'video_duration_seconds': 180,

  // Engagement metrics
  'watch_time_seconds': 135,
  'completion_percent': 75,
  'quality_setting': '1080p',

  // Context
  'source': 'homepage_hero',
  'autoplay': false,
  'muted': false,

  // Behavioral
  'replay_count': 2,
  'seek_count': 3,
  'pause_count': 1
});

Property Data Types

  • String: "Premium Plan"
  • Number: 29.99, 42
  • Boolean: true, false
  • Date: ISO 8601 strings ("2024-01-15T10:30:00Z")
  • Null: null

Note: Heap doesn't support arrays or nested objects in properties.

Implementation Methods

1. JavaScript Snippet (Web)

Installation:

<script type="text/javascript">
  window.heap=window.heap||[],heap.load=function(e,t){window.heap.appid=e,window.heap.config=t=t||{};var r=document.createElement("script");r.type="text/javascript",r.async=!0,r.src="https://cdn.heapanalytics.com/js/heap-"+e+".js";var a=document.getElementsByTagName("script")[0];a.parentNode.insertBefore(r,a);for(var n=function(e){return function(){heap.push([e].concat(Array.prototype.slice.call(arguments,0)))}},p=["addEventProperties","addUserProperties","clearEventProperties","identify","resetIdentity","removeEventProperty","setEventProperties","track","unsetEventProperty"],o=0;o<p.length;o++)heap[p[o]]=n(p[o])};
  heap.load("YOUR_ENV_ID");
</script>

NPM Installation:

npm install heap-js
import heap from 'heap-js';

heap.load('YOUR_ENV_ID');

// Identify user
heap.identify('user_12345');

// Track custom event
heap.track('Feature Used', {
  'feature_name': 'export_data'
});

2. Mobile SDKs

iOS (Swift):

import Heap

// Initialize in AppDelegate
Heap.initialize("YOUR_ENV_ID")

// Identify user
Heap.identify("user_12345")

// Add user properties
Heap.addUserProperties([
    "email": "user@example.com",
    "plan": "Premium"
])

// Track custom event
Heap.track("Level Completed", properties: [
    "level_number": 5,
    "score": 9500,
    "time_seconds": 145
])

// Autocapture works automatically for UI interactions

Android (Kotlin):

import com.heapanalytics.android.Heap

// Initialize in Application class
Heap.init(applicationContext, "YOUR_ENV_ID")

// Identify user
Heap.identify("user_12345")

// Add user properties
Heap.addUserProperties(mapOf(
    "email" to "user@example.com",
    "plan" to "Premium"
))

// Track custom event
Heap.track("Level Completed", mapOf(
    "level_number" to 5,
    "score" to 9500,
    "time_seconds" to 145
))

3. Server-Side API

Heap provides a server-side API for backend events:

import requests
import json

def track_heap_event(user_id, event_name, properties):
    url = "https://heapanalytics.com/api/track"

    payload = {
        "app_id": "YOUR_ENV_ID",
        "identity": user_id,
        "event": event_name,
        "properties": properties
    }

    headers = {
        "Content-Type": "application/json"
    }

    response = requests.post(url, data=json.dumps(payload), headers=headers)
    return response.status_code

# Track event
track_heap_event("user_12345", "Subscription Renewed", {
    "plan": "Pro Annual",
    "price": 299.99
})

Node.js:

const axios = require('axios');

async function trackHeapEvent(userId, eventName, properties) {
  await axios.post('https://heapanalytics.com/api/track', {
    app_id: 'YOUR_ENV_ID',
    identity: userId,
    event: eventName,
    properties: properties
  });
}

// Track event
trackHeapEvent('user_12345', 'API Call Completed', {
  endpoint: '/api/users',
  response_time_ms: 45
});

4. Segment Integration

Heap integrates with Segment as a destination:

// Segment automatically forwards to Heap
analytics.track('Purchase Completed', {
  order_id: 'ORDER_12345',
  revenue: 149.99
});

analytics.identify('user_12345', {
  email: 'user@example.com',
  plan: 'Premium'
});

Debugging & Validation

1. Heap Console

Enable debugging in browser console:

// Check if Heap is loaded
console.log(window.heap);

// Check user identity
console.log(heap.identity);

// Check environment ID
console.log(heap.appid);

// View all queued events (before page loads)
console.log(heap.q);

2. Heap Illuminate (Visual Debugger)

In-app visual debugger:

  1. Install Heap Illuminate browser extension
  2. Navigate to your site
  3. Click Heap icon in browser
  4. See events as they fire in real-time
  5. Inspect event properties
  6. Validate autocapture

3. Live Events View

In Heap dashboard:

  1. Go to Data > Events
  2. Enable Live mode
  3. Perform actions on your site
  4. See events appear within seconds
  5. Click events to inspect properties

4. User Sessions

Watch individual user sessions:

  1. Go to Users > Sessions
  2. Find recent session
  3. Play session replay (if enabled)
  4. See all events in timeline
  5. Validate event properties

5. Network Tab

Monitor Heap beacons:

Filter: heapanalytics.com
Look for: POST requests to /track or /api/track
Inspect: Request payload

6. Event Visualizer

Define and validate events:

  1. Go to Define > Events
  2. Click Create Event
  3. Use visual editor to select element
  4. See how many times it's been clicked historically
  5. Validate with filters

Best Practices

Autocapture Strategy

✅ Do:

  • Let Heap autocapture clicks and pageviews
  • Define events retroactively when you need them
  • Use visual labeling for UI interactions
  • Create event naming standards
  • Regularly review undefined events

❌ Don't:

  • Manually track clicks that are autocaptured
  • Create redundant custom events
  • Ignore the power of retroactive analytics
  • Define hundreds of unused events

Custom Event Usage

✅ Do:

  • Use heap.track() for server-side events
  • Track business logic events (not UI clicks)
  • Include meaningful properties
  • Name events clearly: "Subscription Upgraded"
  • Track conversion milestones

❌ Don't:

  • Track every function call
  • Use for clicks/pageviews (autocaptured)
  • Send events without properties
  • Include sensitive PII

User Identification

Best Practice Flow:

// Anonymous user - Heap auto-assigns identity
// User browses, events autocaptured

// User signs up
heap.identify('user_12345');
heap.addUserProperties({
  'email': 'user@example.com',
  'signup_date': new Date().toISOString(),
  'plan': 'Trial'
});

// User upgrades
heap.addUserProperties({
  'plan': 'Premium',
  'upgrade_date': new Date().toISOString()
});

// User logs out
heap.resetIdentity(); // Creates new anonymous session

// User logs back in
heap.identify('user_12345');

✅ Do:

  • Call identify() once per user session
  • Use permanent IDs (database primary keys)
  • Call identify() on page load for logged-in users
  • Use resetIdentity() on logout for shared devices

❌ Don't:

  • Call identify() repeatedly in same session
  • Use email addresses as user IDs
  • Identify without user consent
  • Create new IDs on each visit

Event Definition Organization

Create clear event hierarchies:

Button Clicks:
  - CTA - Homepage Sign Up
  - CTA - Pricing Page Start Trial
  - Navigation - Header Login

Form Submissions:
  - Form Submit - Contact Us
  - Form Submit - Newsletter Signup

Purchases:
  - Checkout - Started
  - Checkout - Completed
  - Checkout - Abandoned

Privacy & Compliance

✅ Do:

// Disable Heap based on consent
if (!userConsented) {
  heap.config.disableTextCapture = true;
}

// Hash sensitive data
heap.identify(hashUserId(email));

// Exclude sensitive pages
if (window.location.pathname.includes('/admin')) {
  // Don't identify or track
}

❌ Don't:

  • Capture credit card numbers, SSNs
  • Track users without consent
  • Ignore GDPR/CCPA requirements
  • Autocapture on password fields (Heap blocks by default)

Performance

  • Heap snippet loads asynchronously
  • Minimal performance impact (< 50kb)
  • Events batched and sent efficiently
  • No need to manually batch

Data Quality

  • Regularly review autocaptured events
  • Define events for important interactions
  • Use consistent naming conventions
  • Filter out internal traffic (IP exclusion)
  • Test in staging before production

Organizational

  • Maintain event taxonomy documentation
  • Establish naming conventions
  • Create governance for event definitions
  • Regular audits of defined events
  • Train team on Heap's retroactive model

Common Pitfalls

❌ Avoid:

  • Treating Heap like Google Analytics (it's not pageview-focused)
  • Not leveraging retroactive analytics
  • Creating too many custom events for UI interactions
  • Ignoring user property updates
  • Not using session replay for validation

✅ Instead:

  • Embrace autocapture, define events as needed
  • Look backward in data when questions arise
  • Let Heap autocapture UI, use custom events for logic
  • Keep user properties current
  • Use replays to validate tracking assumptions

Additional Resources:

// SYS.FOOTER