Skip to content

Group Properties

Learn how to work with group properties in Voltage Schema.

Setting Group Properties

Groups are strictly typed stateful buckets of properties.

Groups represent entities like users or teams. Or they can represent properties that you want to track with every event.

Their properties can be set independently of events:

typescript
import { createAnalyticsTracker } from 'voltage-schema';
import { AnalyticsTracker, TrackerEvents, trackingConfig } from './__analytics_generated__/analytics';

const tracker = createAnalyticsTracker<TrackerEvents>(trackingConfig, {
  onEventTracked: (eventName, { properties, groups, meta }) => {
    // Send event with group properties
  },
  onGroupUpdated: (groupName, properties) => {
    // Update group traits
  }
});

// Set user properties
tracker.setProperties('User', {
  UserID: 123,
  Role: 'admin'
});

// Set team properties
tracker.setProperties('Team', {
  TeamID: 456,
  Plan: 'PAID'
});

Group Property Types

Group properties are fully type-safe, and support functions or promises that resolve to their expected types.

typescript
// ✅ Valid property setting
tracker.setProperties('User', {
  UserID: 123,
  Role: 'admin'
});

// ✅ Valid function resolving to expected type
tracker.setProperties('User', {
  UserID: 123,
  Role: () => 'admin',
});

// ✅ Valid promise resolving to expected type
tracker.setProperties('User', {
  UserID: 123,
  Role: new Promise((resolve) => resolve('admin')),
});

// ❌ TypeScript error: Invalid group name
tracker.setProperties('InvalidGroup', {
  UserID: 123
});

// ❌ TypeScript error: Missing required property
tracker.setProperties('User', {
  Role: 'admin'
});

// ❌ TypeScript error: Invalid property type
tracker.setProperties('User', {
  UserID: '123', // Should be number
  Role: 'invalid_role' // Should be 'admin' | 'member'
});

Working with Analytics Services

Group properties are automatically included with tracked events:

typescript
import amplitude from 'amplitude-js';

const tracker = createAnalyticsTracker<TrackerEvents>(trackingConfig, {
  onEventTracked: (eventName, { properties, groups, meta }) => {
    // Send to Amplitude with group context
    amplitude.getInstance().logEvent(eventName, {
      ...properties,
      ...groups.User
    });
  },
  onGroupUpdated: (groupName, properties) => {
    // Update group traits in Amplitude
    amplitude.getInstance().setGroup(groupName, properties);
  }
});