Skip to content
  • There are no suggestions because the search field is empty.

Custom Events Guide

Complete guide for tracking custom business events with the OIR SDK.

  1. Overview
  2. Event Structure
  3. Naming Conventions
  4. Event Categories
  5. Basic Events
  6. Advanced Events
  7. Common Use Cases
  8. Framework Integration
  9. Validation
  10. Best Practices

Overview

Custom events allow you to track business-specific interactions that are important to your application. The SDK captures the data with the original structure and delivers it as-is to the destination configured in your dashboard.

You can define any custom events using the standard syntax, including events not listed in this documentation. You can also modify the events listed here to fit your needs—just ensure alignment on the data format with your team.

Benefits

  • Unlimited custom events: Define any event that fits your business needs
  • Standard compliance: Follows industry-standard event structure
  • Original data structure: Data is preserved exactly as sent
  • Flexible delivery: Configure destinations in your dashboard
  • Traffic filtering: Custom event names can be used as traffic filters in connections

Event Structure

Basic Format

_oirtrk.push([
'event',
{
event: 'event_name',
payload: {
// Event properties
},
},
]);
 

Example

_oirtrk.push([
'event',
{
event: 'button_click',
payload: {
event_category: 'engagement',
event_action: 'click',
event_label: 'hero_cta',
button_text: 'Get Started',
page_url: window.location.href,
},
},
]);
 

Naming Conventions

Recommended Structure

Use [object]_[action] pattern with snake_case:

button_click
form_submit
video_play
file_download
page_exit
modal_open
search_performed
filter_applied
 

Do's and Don'ts

✅ Do ❌ Don't
button_click buttonClick
form_submit form-submit
video_play VideoPlay
user_registration userRegistration

 

Event Categories

Organize events into logical categories for better analytics and filtering:

Category Purpose Examples
engagement User interactions button_clicklink_clicktab_switch
conversion Goal completions signup_completetrial_startedlead_generated
navigation Page/section changes page_scrollsection_viewmenu_opened
media Video, audio, image interaction video_playvideo_pauseaudio_complete
forms Form interactions form_startform_submitform_error
errors Error events javascript_errorapi_errorvalidation_failed
search Search interactions search_performedfilter_appliedsort_changed
social Social sharing share_facebookshare_twittershare_email

 

Basic Events

Button Click

Track user interactions with buttons and clickable elements.

Properties:

Property Type Req Description
event string Event name (e.g., button_click)
payload object Event attributes
payload.event_category string Event category (e.g., 'engagement')
payload.event_action string Action performed (e.g., 'click')
payload.event_label string Button identifier or label
payload.button_text string Text displayed on the button
payload.button_id string Button DOM ID or unique identifier
payload.page_url string Current page URL
payload.custom_properties object Additional custom data

Example:

_oirtrk.push([
'event',
{
event: 'button_click',
payload: {
event_category: 'engagement',
event_action: 'click',
event_label: 'hero_cta',
button_text: 'Get Started',
button_id: 'cta-button',
page_url: window.location.href,
},
},
]);
 

User Registration

Track when users complete registration or sign-up.

Properties:

Property Type Req Description
event string Event name (e.g., user_registration)
payload object Event attributes
payload.method string Registration method (email, social, etc.)
payload.source string Where registration was initiated
payload.user_type string User tier or type (free, premium, etc.)
payload.campaign string Marketing campaign identifier
payload.custom_properties object Additional custom data

Example:

_oirtrk.push([
'event',
{
event: 'user_registration',
payload: {
method: 'email',
source: 'landing_page',
user_type: 'premium',
campaign: 'summer_2024',
},
},
]);
 

Feature Usage

Track when users interact with specific features in your application.

Properties:

Property Type Req Description
event string Event name (e.g., feature_used)
payload object Event attributes
payload.feature_name string Name of the feature used
payload.usage_duration integer Time spent using feature (seconds)
payload.success boolean Whether feature usage was successful
payload.user_segment string User segment or category
payload.custom_properties object Additional custom data

Example:

_oirtrk.push([
'event',
{
event: 'feature_used',
payload: {
feature_name: 'advanced_search',
usage_duration: 45,
success: true,
user_segment: 'power_user',
},
},
]);
 

Content Engagement

Track user engagement with content (articles, videos, etc.).

Properties:

Property Type Req Description
event string Event name (e.g., content_engagement)
payload object Event attributes
payload.content_type string Type of content (article, video, etc.)
payload.content_id string Unique content identifier
payload.engagement_time integer Time engaged with content (seconds)
payload.scroll_depth integer Scroll depth percentage (0-100)
payload.custom_properties object Additional custom data

Example:

_oirtrk.push([
'event',
{
event: 'content_engagement',
payload: {
content_type: 'article',
content_id: 'article_123',
engagement_time: 120,
scroll_depth: 75,
},
},
]);
 

Advanced Events

Product Search

Track search queries and results within your application.

Properties:

Property Type Req Description
event string Event name (e.g., product_search)
payload object Event attributes
payload.search_term string User's search query
payload.results_count integer Number of results returned
payload.filters_applied array Array of filters applied
payload.search_duration float Time to complete search (seconds)
payload.user_segment string User segment or category
payload.custom_properties object Additional custom data
payload.custom_properties.search_source string Where search was initiated (header, page)
payload.custom_properties.autocomplete_used boolean Whether autocomplete was used

Example:

_oirtrk.push([
'event',
{
event: 'product_search',
payload: {
search_term: 'wireless headphones',
filters_applied: ['brand', 'price_range'],
results_count: 24,
search_duration: 3.2,
user_segment: 'premium',
custom_properties: {
search_source: 'header',
autocomplete_used: true,
suggestions_shown: 5,
},
},
},
]);
 

Multi-Step Process Tracking

Track users progressing through multi-step flows (checkout, onboarding, etc.).

Step Started Properties:

Property Type Req Description
event string Event name (e.g., checkout_process)
payload object Event attributes
payload.step string Name of current step
payload.step_number integer Current step number (1-based)
payload.total_steps integer Total number of steps in process
payload.process_id string Unique identifier for this process
payload.started_at string ISO timestamp when step started
payload.completed_at string ISO timestamp when step completed
payload.step_duration integer Time spent on step (seconds)
payload.custom_properties object Additional custom data

Example - Step Started:

_oirtrk.push([
'event',
{
event: 'checkout_process',
payload: {
step: 'shipping_info',
step_number: 1,
total_steps: 4,
process_id: 'checkout_123',
started_at: new Date().toISOString(),
},
},
]);
 

Example - Step Completed:

_oirtrk.push([
'event',
{
event: 'checkout_process',
payload: {
step: 'payment_method',
step_number: 2,
total_steps: 4,
process_id: 'checkout_123',
step_duration: 45,
completed_at: new Date().toISOString(),
},
},
]);
 

Process Abandoned Properties:

Property Type Req Description
event string Event name (e.g., checkout_abandoned)
payload object Event attributes
payload.last_step string Name of last completed step
payload.step_number integer Last step number reached
payload.total_steps integer Total steps in process
payload.process_id string Unique process identifier
payload.abandonment_reason string Reason for abandonment (timeout, etc.)
payload.custom_properties object Additional custom data

Example - Process Abandoned:

_oirtrk.push([
'event',
{
event: 'checkout_abandoned',
payload: {
last_step: 'payment_method',
step_number: 2,
total_steps: 4,
process_id: 'checkout_123',
abandonment_reason: 'timeout',
},
},
]);
 

Common Use Cases

User Engagement

Page Scroll

_oirtrk.push([
'event',
{
event: 'page_scroll',
payload: {
scroll_depth: 75,
page: '/products',
time_on_page: 120,
max_scroll_reached: 75,
},
},
]);
 

Time Spent

_oirtrk.push([
'event',
{
event: 'time_spent',
payload: {
section: 'product_details',
duration: 45,
page: '/product/123',
interactions_count: 8,
},
},
]);
 

Video Play

_oirtrk.push([
'event',
{
event: 'video_play',
payload: {
video_id: 'demo_video_001',
video_title: 'Product Demo',
video_duration: 180,
current_time: 0,
source: 'product_page',
},
},
]);
 

Conversion Tracking

Lead Generated

_oirtrk.push([
'event',
{
event: 'lead_generated',
payload: {
lead_type: 'newsletter_signup',
source: 'popup',
campaign: 'summer_promotion',
conversion_value: 5.0,
},
},
]);
 

Trial Started

_oirtrk.push([
'event',
{
event: 'trial_started',
payload: {
plan: 'premium',
trial_duration: 14,
source: 'pricing_page',
initial_value: 29.99,
},
},
]);
 

File Download

_oirtrk.push([
'event',
{
event: 'file_download',
payload: {
file_name: 'product_catalog.pdf',
file_type: 'pdf',
file_size_kb: 2048,
download_source: 'resources_page',
},
},
]);
 

Error Tracking

JavaScript Error

_oirtrk.push([
'event',
{
event: 'javascript_error',
payload: {
error_message: 'Cannot read property of undefined',
error_file: 'app.js',
error_line: 42,
error_column: 15,
user_agent: navigator.userAgent,
page_url: window.location.href,
},
},
]);
 

API Error

_oirtrk.push([
'event',
{
event: 'api_error',
payload: {
endpoint: '/api/users',
method: 'GET',
status_code: 500,
error_message: 'Internal Server Error',
response_time: 1200,
retry_count: 2,
},
},
]);
 

Form Validation Error

_oirtrk.push([
'event',
{
event: 'form_validation_error',
payload: {
form_id: 'checkout_form',
field_name: 'email',
error_type: 'invalid_format',
error_message: 'Please enter a valid email',
},
},
]);
 

Search and Filter

Search Performed

_oirtrk.push([
'event',
{
event: 'search_performed',
payload: {
search_term: 'wireless headphones',
results_count: 24,
search_location: 'header',
filters_active: false,
},
},
]);
 

Filter Applied

_oirtrk.push([
'event',
{
event: 'filter_applied',
payload: {
filter_type: 'price_range',
filter_value: '50-100',
results_before: 100,
results_after: 24,
page: '/products',
},
},
]);
 

Wishlist

_oirtrk.push([
'event',
{
event: 'added_to_wishlist',
payload: {
item_id: 'ITM-12345',
item_name: 'Awesome T-Shirt',
item_brand: 'Nike',
item_category: 'Apparel',
price: 29.99,
custom_attributes: {
wishlist_id: 'wishlist_001',
user_segment: 'premium',
},
},
},
]);
 

Framework Integration

React

import { useEffect } from 'react';

function ProductCard({ product }) {
const handleView = () => {
window._oirtrk.push([
'event',
{
event: 'product_viewed',
payload: {
product_id: product.id,
product_name: product.name,
category: product.category,
price: product.price,
view_source: 'product_card',
},
},
]);
};

const handleAddToCart = () => {
window._oirtrk.push([
'event',
{
event: 'add_to_cart_clicked',
payload: {
product_id: product.id,
product_name: product.name,
price: product.price,
quantity: 1,
},
},
]);
};

useEffect(() => {
// Track card impression
window._oirtrk.push([
'event',
{
event: 'product_card_impression',
payload: {
product_id: product.id,
position: product.index,
list_name: 'product_grid',
},
},
]);
}, [product.id]);

return (
<div onClick={handleView}>
<h3>{product.name}</h3>
<p>${product.price}</p>
<button onClick={handleAddToCart}>Add to Cart</button>
</div>
);
}
 

Vue

<template>
<div class="product-card">
<button @click="trackClick">

</button>
<div @mouseenter="trackHover">
<img :src="product.image" @load="trackImageLoad" />
</div>
</div>
</template>

<script>
export default {
props: {
product: Object,
buttonText: String,
},
methods: {
trackClick() {
window._oirtrk.push([
'event',
{
event: 'button_click',
payload: {
button_id: this.buttonId,
page: this.$route.path,
component: 'CustomButton',
product_id: this.product.id,
},
},
]);
},
trackHover() {
window._oirtrk.push([
'event',
{
event: 'product_hover',
payload: {
product_id: this.product.id,
product_name: this.product.name,
hover_location: 'product_card',
},
},
]);
},
trackImageLoad() {
window._oirtrk.push([
'event',
{
event: 'product_image_loaded',
payload: {
product_id: this.product.id,
image_url: this.product.image,
load_time: performance.now(),
},
},
]);
},
},
mounted() {
// Track component mount
window._oirtrk.push([
'event',
{
event: 'component_mounted',
payload: {
component_name: 'ProductCard',
product_id: this.product.id,
},
},
]);
},
};
</script>
 

Angular

import { Component, OnInit, Input } from '@angular/core';

@Component({
selector: 'app-product-card',
templateUrl: './product-card.component.html',
})
export class ProductCardComponent implements OnInit {
@Input() product: any;

ngOnInit() {
this.trackImpression();
}

trackImpression() {
(window as any)._oirtrk.push([
'event',
{
event: 'product_impression',
payload: {
product_id: this.product.id,
product_name: this.product.name,
category: this.product.category,
},
},
]);
}

trackClick() {
(window as any)._oirtrk.push([
'event',
{
event: 'product_click',
payload: {
product_id: this.product.id,
click_source: 'product_card',
},
},
]);
}
}
 

Validation

Validation Function

function validateCustomEvent(event, data) {
if (!event || typeof event !== 'string') {
throw new Error('Event name is required and must be a string');
}

if (!data || typeof data !== 'object') {
throw new Error('Event data must be an object');
}

// Validate common properties
if (data.event_category && typeof data.event_category !== 'string') {
throw new Error('event_category must be a string');
}

if (data.value !== undefined && typeof data.value !== 'number') {
throw new Error('value must be a number');
}

// Validate naming convention
if (!/^[a-z][a-z0-9_]*$/.test(event)) {
console.warn(`Event name "${event}" does not follow naming convention (snake_case)`);
}

return true;
}
 

Usage

try {
const eventName = 'button_click';
const eventData = {
event_category: 'engagement',
event_action: 'click',
value: 1,
};

validateCustomEvent(eventName, eventData);

window._oirtrk.push([
'event',
{
event: eventName,
payload: eventData,
},
]);
} catch (error) {
console.error('Custom event validation failed:', error);
}
 

Best Practices

1. Consistent Naming

  • Use snake_case for all event names
  • Be descriptive but concise
  • Follow a consistent pattern across your application
  • Start with the object/noun, followed by the action/verb

2. Meaningful Data

  • Include relevant context in your payload
  • Use appropriate data types
  • Avoid including sensitive personal information

3. Keep Payloads Reasonable

// ❌ BAD - Unnecessary data
{
event: 'button_click',
payload: {
unnecessary_field_1: null,
unnecessary_field_2: undefined,
unused_metadata: {}
}
}

// ✅ GOOD - Clean payload
{
event: 'button_click',
payload: {
button_id: 'cta-button',
page: '/home'
}
}
 

4. Use Consistent Property Names

// Use the same property names everywhere
{
event: 'product_viewed',
payload: {
product_id: product.sku, // Always use product_id
product_name: product.title, // Always use product_name
price: product.price,
quantity: product.qty
}
}
 

5. Privacy Compliance

  • Don't include PII in event data—use the identify function instead
  • Follow GDPR, CCPA regulations
  • Only track necessary data

Next Steps