Back to Documentation
guides

Event tracking guide

Track product usage events to power Customer Insights health scores and customer health monitoring.

Last Updated: January 25, 2025

Overview

Event tracking allows you to monitor how customers use your product. Events are automatically batched (20 per batch) and sent to FirstDistro every 5 seconds or on page unload.

Prerequisites: Before tracking events, ensure you've completed the Getting Started guide - specifically installing the SDK (see Installation Guide) and enabling event tracking.

Basic tracking

Track an event

FirstDistro.track('event_name', {
  property1: 'value1',
  property2: 'value2'
});

Example events

// User actions
FirstDistro.track('user_signed_up', { plan: 'pro', source: 'website' });
FirstDistro.track('user_logged_in', { method: 'email' });
FirstDistro.track('user_logged_out');

// Feature usage
FirstDistro.track('feature_used', { 
  feature: 'export', 
  format: 'pdf',
  page_count: 10
});

FirstDistro.track('feature_used', { 
  feature: 'import', 
  file_type: 'csv',
  row_count: 1000
});

// Page views
FirstDistro.track('page_viewed', { 
  page: '/dashboard',
  referrer: '/login'
});

// Milestones
FirstDistro.track('milestone_reached', {
  milestone: '100_users',
  user_count: 100
});

FirstDistro.track('milestone_reached', {
  milestone: 'first_payment',
  amount: 99.00
});

User identification

Identify users to track individual user behavior:

FirstDistro.identify('user-123', {
  name: 'John Doe',
  email: 'john@example.com',
  role: 'admin',
  plan: 'pro'
});

When to call:

  • After user logs in
  • When user profile loads
  • When user updates their profile

⚠️ Important: Always call identify() before group(). This ensures user identification is properly set up before account grouping.

Account grouping

Group users into accounts (organizations/companies):

FirstDistro.group('account-456', {
  name: 'Acme Corp',
  industry: 'SaaS',
  plan: 'enterprise',
  user_count: 25
});

When to call:

  • After user logs in (if account context available)
  • When account information loads
  • When account details change

⚠️ Important:

  • Always call identify() first, then group()
  • Do NOT put user data (user_id, user_email, etc.) in group() traits
  • Use identify() for user information, group() for account information

Account grouping required for customer insights

Important: Customer Insights requires account grouping to function. Without FirstDistro.group():

  • ✅ Events are stored in the database
  • ❌ Events are not processed for health scoring
  • ❌ Customers won't appear in Customer Insights dashboard
  • ❌ Health scores won't be calculated
  • ❌ Alerts won't be generated

With account grouping:

  • ✅ Events are stored with account_id
  • ✅ Events are aggregated into customer_accounts table
  • ✅ Health scores are calculated hourly
  • ✅ Customers appear in Customer Insights dashboard
  • ✅ Alerts are generated for at-risk customers

Setup: See the Getting Started guide for account grouping setup instructions.

Correct pattern: identify()group()track()

// Step 1: Identify the USER first (required)
FirstDistro.identify(user.id, {
  name: user.name,
  email: user.email,
  role: user.role
});

// Step 2: Group to the ACCOUNT (after identify)
FirstDistro.group(account.id, {
  name: account.name,
  plan: account.plan,
  industry: account.industry
  // ❌ Do NOT put user data here (user_id, user_email, etc.)
});

// Step 3: Track events (now has both user_id and account_id)
FirstDistro.track('feature_used', { feature: 'export' });
// This event will be processed for health scoring ✅

Common mistake to avoid:

// ❌ WRONG: Putting user data in group() traits
FirstDistro.group(account.id, {
  name: account.name,
  user_id: user.id,        // ❌ Don't do this
  user_email: user.email   // ❌ Don't do this
});

// ✅ CORRECT: Use identify() for user data
FirstDistro.identify(user.id, {
  email: user.email  // ✅ User data here
});
FirstDistro.group(account.id, {
  name: account.name  // ✅ Account data here
});

Advanced patterns: For complex account grouping scenarios (multiple accounts, account switching, etc.), see the API Reference.

Recommended events

Track these events for best Customer Insights:

1. authentication events

  • user_signed_up - New user registration
  • user_logged_in - User login
  • user_logged_out - User logout

2. feature usage events

  • feature_used - Any feature interaction
  • data_imported - Data import completed
  • data_exported - Data export completed
  • report_generated - Report created

3. milestone events

  • milestone_reached - Important milestones
  • first_feature_used - First feature interaction
  • milestone_100_users - User count milestones
  • milestone_1000_users - User count milestones

4. engagement events

  • page_viewed - Page navigation
  • session_started - Session begins
  • session_ended - Session ends

Event properties

Include relevant properties with each event:

FirstDistro.track('feature_used', {
  // Feature details
  feature: 'export',
  feature_category: 'data',
  
  // Usage context
  format: 'pdf',
  page_count: 10,
  file_size_kb: 250,
  
  // User context (auto-added if identified)
  user_id: 'user-123', // Auto-added
  account_id: 'account-456', // Auto-added after group() call
  
  // Custom properties
  source: 'dashboard',
  workflow: 'monthly_report'
});

Event batching

Events are automatically batched:

  • Batch size: 20 events per batch
  • Flush interval: 5 seconds
  • Unload flush: Events sent on page close using sendBeacon()

You don't need to manage batching - it's handled automatically!

Best practices

1. track key user actions

Focus on actions that indicate product value:

  • Feature usage
  • Data operations
  • User milestones
  • Engagement patterns

2. use consistent event names

Use snake_case and be descriptive:

  • user_signed_up
  • feature_used
  • milestone_reached
  • signup (too vague)
  • click (not descriptive)

3. include relevant properties

Add properties that provide context:

  • Feature names
  • User/account identifiers
  • Quantities (counts, sizes, etc.)
  • Timestamps (auto-added)

4. follow the correct order: identify() → group() → track()

Always call identify() before group():

// Step 1: Identify user first (after login)
FirstDistro.identify(user.id, {
  name: user.name,
  email: user.email,
  role: user.role
});

// Step 2: Group to account (after identify)
FirstDistro.group(account.id, {
  name: account.name,
  plan: account.plan,
  industry: account.industry
  // ❌ Do NOT put user data here
});

// Step 3: Track events (both user_id and account_id auto-attached)
FirstDistro.track('feature_used', { feature: 'export' });

Why this order matters:

  • identify() sets user context that gets attached to all future events
  • group() sets account context on top of user context
  • Both user_id and account_id are automatically included in tracked events
  • This ensures proper data structure in the database

Examples

React integration

Step 1: Add the script tag to your public/index.html:

<!-- Add before closing </body> tag -->
<script src="https://firstdistro.com/sdk/install/fd_your-token-here.js"></script>

Step 2: Use the SDK in your React components:

function App() {
  useEffect(() => {
    // SDK is automatically initialized after script loads
    // Identify user after login
    if (user) {
      FirstDistro.identify(user.id, {
        name: user.name,
        email: user.email
      });
    }
    
    // Group by account
    if (account) {
      FirstDistro.group(account.id, {
        name: account.name,
        plan: account.plan
      });
    }
  }, [user, account]);
  
  const handleFeatureUse = () => {
    FirstDistro.track('feature_used', {
      feature: 'export',
      format: 'pdf'
    });
  };
  
  return <button onClick={handleFeatureUse}>Export</button>;
}

Get your token: Dashboard → Settings → SDK Configuration

Next.js integration

// app/layout.tsx
import Script from 'next/script';

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        <Script
          src="https://firstdistro.com/sdk/install/fd_your-token-here.js"
          strategy="afterInteractive"
        />
        {children}
      </body>
    </html>
  );
}

Then use the SDK in your pages:

// app/page.tsx
'use client';

import { useEffect } from 'react';

export default function HomePage() {
  useEffect(() => {
    if (typeof window === 'undefined' || !window.FirstDistro) return;

    // SDK is automatically initialized
    // Identify and group when user/account data is available
    if (user) {
      window.FirstDistro.identify(user.id, {
        name: user.name,
        email: user.email
      });
    }
    
    if (account) {
      window.FirstDistro.group(account.id, {
        name: account.name,
        plan: account.plan
      });
    }
    
    window.FirstDistro.track('page_viewed', { page: '/' });
  }, []);

  return <div>Welcome</div>;
}

See the Installation Guide for complete setup instructions.

Troubleshooting

Events not sending?

  • Check tracking is enabled in dashboard
  • Verify API key is correct
  • Check browser console for errors
  • Verify network requests in Network tab

Events delayed?

  • Events are batched (up to 5 seconds delay)
  • Events flush on page unload
  • This is normal behavior

Too many events?

  • Use sample rate in dashboard config
  • Filter events client-side before tracking
  • Batch related events together

Customers not appearing in Customer Insights?

  • Ensure you've called FirstDistro.group() with account ID
  • Verify events include account_id (check browser console)
  • See Getting Started guide for setup

"No users found" in Customer Detail Modal?

  • Ensure you've called FirstDistro.identify() before group()
  • Verify identify() is called with user ID and traits (name, email)
  • Check that events include user_id (check browser console)
  • See API Reference for correct usage pattern

For more help, see the API Reference or email us at jide@firstdistro.com.