Skip to main content

Custom Events

Custom events let you track business-specific actions that automatic tracking doesn't capture: sign-ups, purchases, feature usage, onboarding steps, and anything else meaningful to your product.

Basic Usage

import { tracelog } from '@tracelog/lib';

// Simple event (no metadata)
tracelog.event('onboarding_completed');

// Event with metadata
tracelog.event('purchase_completed', {
orderId: 'ORD-789',
total: 149.99,
currency: 'USD'
});

tracelog.event() must be called after tracelog.init().

Signature

tracelog.event(name: string, metadata?: Record<string, MetadataType> | Record<string, MetadataType>[]): void
ParameterTypeRequiredDescription
namestringYesEvent name identifier
metadataobject or object[]NoAdditional data attached to the event

Metadata Types

Values in the metadata object can be:

  • Primitives: string, number, boolean
  • Arrays of strings
  • Nested objects (1 level deep)

Not allowed: functions, symbols, undefined, deeply nested objects.

Limits: 100 keys max, 48KB total, 500 items per array, 1000 characters per string (500 for strings inside arrays).

Naming Conventions

Use snake_case for event names. Descriptive verb-noun pairs work best:

// Good
tracelog.event('trial_started');
tracelog.event('feature_used', { featureId: 'dark-mode' });
tracelog.event('purchase_completed', { total: 99 });
tracelog.event('plan_upgraded', { from: 'starter', to: 'pro' });

// Avoid
tracelog.event('click'); // Too generic — automatic tracking already captures clicks
tracelog.event('Event1'); // Not descriptive
tracelog.event('userDidSomething'); // camelCase, hard to read in dashboard
tip

Once you set an event name, it shows up in your Event Catalog. Consistent naming keeps your catalog readable as the product grows.

Examples by Vertical

SaaS

// Onboarding
tracelog.event('account_created');
tracelog.event('onboarding_step_completed', { step: 'connect_integration', stepNumber: 2 });
tracelog.event('onboarding_completed');

// Feature usage
tracelog.event('feature_used', { featureId: 'export-csv', plan: 'pro' });
tracelog.event('report_generated', { reportType: 'weekly', recipients: 3 });

// Billing
tracelog.event('trial_started', { planId: 'pro', trialDays: 14 });
tracelog.event('plan_upgraded', { from: 'starter', to: 'pro', mrr: 49 });
tracelog.event('plan_downgraded', { from: 'pro', to: 'starter', reason: 'too_expensive' });
tracelog.event('subscription_cancelled', { reason: 'no_longer_needed', tenure: 6 });

E-commerce

// Product discovery
tracelog.event('product_viewed', { productId: 'SKU-123', category: 'electronics', price: 299 });
tracelog.event('search_performed', { query: 'wireless headphones', resultsCount: 42 });

// Cart
tracelog.event('cart_item_added', { productId: 'SKU-123', quantity: 1, price: 299 });
tracelog.event('cart_abandoned', { itemCount: 3, cartValue: 149.97 });

// Checkout
tracelog.event('checkout_started', { cartValue: 149.97, itemCount: 3 });
tracelog.event('purchase_completed', {
orderId: 'ORD-789',
total: 149.97,
currency: 'EUR',
itemCount: 3
});

Marketing / Lead Gen

// Lead capture
tracelog.event('newsletter_subscribed', { source: 'footer-form' });
tracelog.event('demo_requested', { company: 'Acme Inc', plan: 'enterprise' });
tracelog.event('contact_form_submitted', { subject: 'pricing' });

// Content engagement
tracelog.event('video_played', { videoId: 'demo-tour', durationSeconds: 120 });
tracelog.event('webinar_registered', { webinarId: 'q1-launch' });

Array Metadata

Pass an array when the event represents multiple items:

tracelog.event('cart_updated', [
{ productId: 'SKU-123', quantity: 2, price: 299 },
{ productId: 'SKU-456', quantity: 1, price: 49 }
]);

Privacy

You are responsible for sanitizing metadata before passing it to tracelog.event(). Do not include PII.

// Do NOT send PII
tracelog.event('user_registered', {
email: user.email, // PII — do not send
phone: user.phone, // PII — do not send
});

// Send safe identifiers instead
tracelog.event('user_registered', {
userId: user.id, // Internal ID, not personal data
plan: 'starter'
});

TraceLog auto-sanitizes text fields (error messages, click text) but does not sanitize values you pass explicitly via tracelog.event().

Rate Limiting

TraceLog enforces multiple rate limits to prevent accidental event floods:

  • 60 per minute per event name
  • 50 per second across all custom events
  • 500 custom events per session

If you hit these limits in development, it usually indicates an event being fired inside a render loop.

Connecting Events to Product Features

After sending custom events, configure them in the TraceLog dashboard:

  1. Event Catalog (Events page) — Assign a semantic type (Conversion, Goal, Feature Usage) to each event. This powers the Goals, Funnels, and Reports features.
  2. Revenue Tracking — If an event has a value field (e.g., total), configure it in Revenue Tracking to aggregate revenue metrics.
  3. Funnels — Chain multiple events into a funnel to see where users drop off in a multi-step flow.

See Goals & Conversions for the full walkthrough.