Overview
Custom properties allow you to attach additional context to events. Properties are key-value pairs that provide details about user actions, product attributes, transaction values, or any other relevant data.
Valid Property Types
Databuddy supports the following JavaScript/TypeScript types for event properties:
type PropertyValue = string | number | boolean | null | undefined ;
type EventProperties = Record < string , PropertyValue >;
Unsupported types: Arrays, objects, functions, and symbols are not supported. Flatten nested data into separate properties.// Bad - nested object
track ( 'purchase' , {
product: { id: '123' , name: 'Widget' } // Don't do this
});
// Good - flattened properties
track ( 'purchase' , {
productId: '123' ,
productName: 'Widget'
});
Adding Properties to Events
Custom Events
Add properties as the second argument to track():
import { track } from '@databuddy/sdk' ;
track ( 'purchase_completed' , {
orderId: 'order-789' ,
total: 99.99 ,
currency: 'USD' ,
itemCount: 2 ,
paymentMethod: 'credit_card' ,
isFirstPurchase: true ,
discountCode: null
});
Pageview Properties
Add properties to screenView() calls:
if ( typeof window !== 'undefined' ) {
window . databuddy ?. screenView ({
section: 'dashboard' ,
viewMode: 'grid' ,
filtersActive: true ,
resultCount: 42
});
}
Global Properties
Set properties that will be attached to all future events :
if ( typeof window !== 'undefined' ) {
window . databuddy ?. setGlobalProperties ({
plan: 'enterprise' ,
region: 'us-west' ,
abTestVariant: 'checkout-v2' ,
userRole: 'admin'
});
}
Global properties are merged with event-specific properties. If a property key exists in both, the event-specific value takes precedence.
Automatic Properties
Databuddy automatically adds the following properties to all events:
Base Context
Full URL including origin, pathname, search, and hash.
Document title from the <title> element.
Previous page URL or "direct" if no referrer.
Browser viewport dimensions (e.g., "1920x1080").
User’s timezone (e.g., "America/New_York").
Browser language (e.g., "en-US").
UTM Parameters
Marketing parameters are automatically extracted from the URL:
Campaign source (e.g., "google", "newsletter").
Marketing medium (e.g., "cpc", "email").
Campaign name (e.g., "spring_sale_2024").
A/B test content identifier.
Identity Properties
Persistent anonymous user identifier.
Current session identifier.
Event timestamp in milliseconds.
Property Naming Conventions
Use camelCase for property keys to maintain consistency with JavaScript conventions:
// Good
track ( 'form_submitted' , {
formId: 'contact-form' ,
formType: 'contact' ,
fieldCount: 5 ,
validationErrors: 0
});
// Also acceptable (snake_case)
track ( 'form_submitted' , {
form_id: 'contact-form' ,
form_type: 'contact' ,
field_count: 5 ,
validation_errors: 0
});
Reserved Prefixes
Avoid using these prefixes for custom properties:
__ (double underscore) - Reserved for internal properties
utm_ - Reserved for UTM parameters
did_ - Reserved for Databuddy internal use
Descriptive Names
Choose property names that are self-explanatory:
// Bad
track ( 'event' , { t: 'user' , v: 100 });
// Good
track ( 'profile_updated' , {
userType: 'premium' ,
profileCompleteness: 100
});
Common Property Patterns
E-commerce Properties
import { track } from '@databuddy/sdk' ;
track ( 'product_viewed' , {
productId: 'sku-123' ,
productName: 'Premium Widget' ,
category: 'widgets' ,
subcategory: 'premium' ,
price: 29.99 ,
currency: 'USD' ,
availability: 'in_stock' ,
brand: 'Acme' ,
sku: 'WGT-PRM-001'
});
track ( 'cart_updated' , {
action: 'add' ,
productId: 'sku-123' ,
quantity: 2 ,
cartTotal: 59.98 ,
cartItemCount: 3
});
User Properties
import { track } from '@databuddy/sdk' ;
track ( 'signup_completed' , {
signupMethod: 'email' ,
referralSource: 'organic' ,
plan: 'free' ,
industry: 'technology' ,
companySize: '11-50'
});
track ( 'subscription_upgraded' , {
previousPlan: 'starter' ,
newPlan: 'professional' ,
billingCycle: 'annual' ,
mrr: 99.00
});
Content Properties
import { track } from '@databuddy/sdk' ;
track ( 'article_viewed' , {
articleId: 'blog-123' ,
articleTitle: 'Getting Started Guide' ,
category: 'tutorials' ,
author: 'John Doe' ,
publishDate: '2024-01-15' ,
wordCount: 1500 ,
readingTime: 6
});
track ( 'video_played' , {
videoId: 'vid-456' ,
videoTitle: 'Product Demo' ,
duration: 180 ,
quality: '1080p' ,
isAutoplay: false
});
Feature Usage Properties
import { track } from '@databuddy/sdk' ;
track ( 'feature_used' , {
feature: 'export' ,
exportFormat: 'csv' ,
rowCount: 1500 ,
columns: 12 ,
includeHeaders: true ,
processingTime: 2.3
});
track ( 'search_performed' , {
searchTerm: 'analytics dashboard' ,
resultCount: 42 ,
filterApplied: true ,
sortOrder: 'relevance' ,
page: 1
});
Error Tracking
Databuddy provides a convenience function for tracking errors with structured properties:
import { trackError } from '@databuddy/sdk' ;
try {
await riskyOperation ();
} catch ( error ) {
trackError ( error . message , {
filename: error . fileName ,
lineno: error . lineNumber ,
colno: error . columnNumber ,
stack: error . stack ,
error_type: error . name ,
context: 'checkout_flow' ,
userId: currentUser . id
});
}
Error Property Types
function trackError (
message : string ,
properties ?: {
filename ?: string ;
lineno ?: number ;
colno ?: number ;
stack ?: string ;
error_type ?: string ;
[ key : string ] : string | number | boolean | null | undefined ;
}
) : void
The trackError() function is a wrapper around track('error', ...) that provides better TypeScript types for error-specific properties.
Dynamic Properties
Computed Values
import { track } from '@databuddy/sdk' ;
const startTime = Date . now ();
// ... perform operation ...
track ( 'operation_completed' , {
operation: 'data_export' ,
duration: Date . now () - startTime ,
recordCount: records . length ,
success: true
});
Conditional Properties
import { track } from '@databuddy/sdk' ;
track ( 'checkout_initiated' , {
cartValue: cart . total ,
itemCount: cart . items . length ,
... ( discount && { discountCode: discount . code , discountAmount: discount . amount }),
... ( user . isLoggedIn && { userId: user . id , membershipLevel: user . level })
});
Best Practices
Keep It Simple Only include properties that provide actionable insights. Avoid tracking every possible data point.
Use Consistent Types Keep property types consistent across events. Don’t use orderId as a number in one event and a string in another.
Avoid PII Don’t track personally identifiable information (email, phone, address) in event properties unless necessary.
Document Your Events Maintain a tracking plan that documents event names, properties, and their meanings for your team.
Property Limits
Size Limits:
Property keys: Maximum 256 characters
String values: Maximum 1024 characters
Total properties per event: Recommended maximum of 50
Exceeding these limits may result in truncated data or dropped events.