Event tracking guide

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

Last Updated: November 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
});

Setting user and account context (recommended)

Use setup() to set both user and account context in one call. This is the recommended approach as it handles the correct ordering automatically.

FirstDistro.setup({
  user: { 
    id: 'user-123', 
    name: 'John Doe', 
    email: 'john@example.com',
    role: 'admin'
  },
  account: { 
    id: 'account-456', 
    name: 'Acme Corp', 
    plan: 'enterprise',
    industry: 'SaaS'
  }
});

When to call:

  • After user logs in
  • When user/account information loads
  • When switching accounts (just pass the new account)

Benefits of setup():

  • One method instead of two
  • Impossible to get the ordering wrong
  • Cleaner, more readable code

Updating context:

// Update only user traits
FirstDistro.setup({
  user: { id: 'user-123', role: 'superadmin' }
});

// Switch to a different account
FirstDistro.setup({
  account: { id: 'new-account', name: 'New Team', plan: 'pro' }
});

User identification (legacy)

Note: We recommend using setup() instead. See Setting user and account context above.

For granular control, you can identify users separately:

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

⚠️ Important: If using legacy methods, always call group() BEFORE identify() to ensure the user is linked to the account context.

Account grouping (legacy)

Note: We recommend using setup() instead. See Setting user and account context above.

For granular control, you can group users into accounts separately:

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

⚠️ Important:

  • Always call group() FIRST, then identify()
  • Do NOT put user data (user_id, user_email, etc.) in group() traits

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.

Recommended pattern: setup()track()

// Set user and account context in one call
FirstDistro.setup({
  user: { id: user.id, name: user.name, email: user.email },
  account: { id: account.id, name: account.name, plan: account.plan }
});

// Track events (user_id and account_id auto-attached)
FirstDistro.track('feature_used', { feature: 'export' });
// This event will be processed for health scoring ✅

Legacy pattern (still supported): group()identify()track()

// Step 1: Group to the ACCOUNT FIRST (sets account context)
FirstDistro.group(account.id, {
  name: account.name,
  plan: account.plan
});

// Step 2: Identify the USER SECOND (now linked to account)
FirstDistro.identify(user.id, {
  name: user.name,
  email: user.email
});

// Step 3: Track events
FirstDistro.track('feature_used', { feature: 'export' });

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

Handling logout

When a user logs out of your application, you must call FirstDistro.reset() to clear the current user session. This ensures that subsequent events are not incorrectly attributed to the previous user.

// Example: Call this in your logout handler
function handleLogout() {
  // Clear FirstDistro user context BEFORE signing out
  if (window.FirstDistro) {
    FirstDistro.reset();
  }
  
  // ... your existing logout logic ...
}

Why this matters:

  • The SDK persists user_id and account_id in localStorage
  • Without reset(), a new user logging in may inherit the previous user's context
  • This can cause events to be incorrectly attributed, polluting your analytics data

When to call reset():

  • User clicks "Log out" or "Sign out"
  • User session expires
  • Before switching between accounts (if your app supports multiple accounts)

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. use setup() for context

Use setup() to set user and account context - it handles the ordering automatically:

// Set user and account context in one call
FirstDistro.setup({
  user: { id: user.id, name: user.name, email: user.email },
  account: { id: account.id, name: account.name, plan: account.plan }
});

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

Why use setup():

  • Handles correct ordering internally (account before user)
  • Both user_id and account_id are automatically included in tracked events
  • This ensures user data appears correctly in Customer Insights

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
    if (user && account) {
      // Set user and account context in one call
      FirstDistro.setup({
        user: { id: user.id, name: user.name, email: user.email },
        account: { id: 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
    if (user && account) {
      // Set user and account context in one call
      window.FirstDistro.setup({
        user: { id: user.id, name: user.name, email: user.email },
        account: { id: 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.