Custom Events
Track specific actions and conversions on your website
Custom events let you track specific user actions beyond pageviews—things like button clicks, form submissions, video plays, purchases, or any other interaction that matters to your business.
What Are Custom Events?
While pageviews tell you where users go, custom events tell you what they do. Track actions like:
- Button clicks (CTA, download, signup)
- Form submissions
- Video plays/completions
- File downloads
- Add to cart actions
- Purchases/conversions
- Feature usage
- Scroll depth
- Time on page milestones
How to Track Custom Events
BrandJet provides a simple JavaScript API for tracking custom events. Once your tracking script is installed, you have access to the global window.bjTrack object.
Basic Syntax
window.bjTrack.event('event_name', eventData);Parameters:
event_name(required) - Name of the event (alphanumeric + underscores only, max 50 characters)eventData(optional) - Object containing additional data about the event
Simple Example
Track a button click:
// Track a button click
window.bjTrack.event('cta_click');Example with Data
Track a button click with additional context:
window.bjTrack.event('cta_click', {
button_text: 'Get Started',
location: 'hero_section',
plan: 'premium'
});##Real-World Examples
Track Button Clicks
<button onclick="window.bjTrack.event('signup_clicked', { source: 'homepage' })">
Sign Up Now
</button>Track Form Submissions
document.getElementById('contact-form').addEventListener('submit', function(e) {
window.bjTrack.event('form_submitted', {
form_type: 'contact',
form_id: 'contact-form'
});
});Track File Downloads
<a
href="/whitepaper.pdf"
download
onclick="window.bjTrack.event('download', { file: 'whitepaper.pdf', type: 'pdf' })"
>
Download Whitepaper
</a>Track Video Plays
const video = document.getElementById('promo-video');
video.addEventListener('play', () => {
window.bjTrack.event('video_play', {
video_id: 'promo-video',
video_title: 'Product Demo'
});
});
video.addEventListener('ended', () => {
window.bjTrack.event('video_complete', {
video_id: 'promo-video',
video_title: 'Product Demo'
});
});Track Add to Cart
function addToCart(productId, productName, price) {
// Your add to cart logic
// Track the event
window.bjTrack.event('add_to_cart', {
product_id: productId,
product_name: productName,
price: price,
currency: 'USD'
});
}Track Purchases/Conversions
function trackPurchase(orderId, total, items) {
window.bjTrack.event('purchase', {
order_id: orderId,
total: total,
items_count: items.length,
currency: 'USD'
});
}Track Feature Usage
// Dark mode toggle
document.getElementById('dark-mode-toggle').addEventListener('click', () => {
window.bjTrack.event('dark_mode_toggle', {
new_state: document.body.classList.contains('dark') ? 'dark' : 'light'
});
});
// Search usage
document.getElementById('search-input').addEventListener('submit', (e) => {
window.bjTrack.event('search', {
query: e.target.value,
results_count: getSearchResults().length
});
});Scroll-Based Events
Want to track when users scroll to specific sections? Use the data-bj-scroll attribute:
How It Works
Add data-bj-scroll="event_name" to any element. When it becomes visible (scrolled into view), the event fires automatically.
Examples
Track scroll to pricing:
<section id="pricing" data-bj-scroll="viewed_pricing">
<!-- Your pricing content -->
</section>Track scroll to testimonials:
<section id="testimonials" data-bj-scroll="viewed_testimonials">
<!-- Your testimonials -->
</section>Track scroll to CTA:
<div class="cta-section" data-bj-scroll="viewed_footer_cta">
<button>Get Started</button>
</div>How Scroll Tracking Works:
- Events fire when the element is 25% visible in the viewport
- Each event only fires once per page load
- Uses
IntersectionObserverAPI (automatically polyfilled for older browsers) - No performance impact
Outbound Link Tracking
External links are automatically tracked as custom events! No setup needed.
What Gets Tracked:
When a user clicks a link to an external domain, we automatically track:
// Automatic event
{
eventName: 'outbound_link',
eventData: {
url: 'https://external-site.com/page',
hostname: 'external-site.com',
path: '/page',
target: '_blank' // or '_self'
}
}This helps you understand:
- Which external links users click
- Affiliate link performance
- Social media clicks
- Partner link engagement
Event Naming Best Practices
DO:
✅ Use descriptive, action-based names
✅ Use snake_case (lowercase with underscores)
✅ Be specific: signup_completed not just signup
✅ Include context: hero_cta_clicked vs footer_cta_clicked
DON'T:
❌ Use spaces or special characters
❌ Use vague names like click or event1
❌ Make names too long (50 character limit)
❌ Use the same name for different actions
Good Examples:
signup_completedplan_selected_premiumvideo_play_homepageform_submit_contactdownload_whitepaperfeature_toggle_dark_mode
Bad Examples:
click(too vague)Button Click!(has space and special character)user-signed-up-for-premium-plan-from-homepage(too long)event1(not descriptive)
Event Data Best Practices
Keep It Relevant
Only include data that helps you understand the action:
Good:
window.bjTrack.event('video_play', {
video_id: 'intro_video',
duration: 120,
quality: '1080p'
});Too Much:
window.bjTrack.event('video_play', {
video_id: 'intro_video',
duration: 120,
quality: '1080p',
user_agent: navigator.userAgent, // Already tracked automatically
timestamp: Date.now(), // Already tracked automatically
page_url: window.location.href // Already tracked automatically
});Use Consistent Property Names
Stick to a naming convention across all events:
Consistent:
window.bjTrack.event('product_view', { product_id: '123', product_name: 'Widget' });
window.bjTrack.event('add_to_cart', { product_id: '123', product_name: 'Widget' });
window.bjTrack.event('purchase', { product_id: '123', product_name: 'Widget' });Inconsistent:
window.bjTrack.event('product_view', { productId: '123', name: 'Widget' });
window.bjTrack.event('add_to_cart', { product_id: '123', productName: 'Widget' });
window.bjTrack.event('purchase', { id: '123', product: 'Widget' });What Gets Tracked Automatically
Every custom event automatically includes:
- Visitor ID - Anonymized visitor identifier
- URL - Page where event occurred
- Timestamp - When the event happened
- Referrer - Where the visitor came from
- Screen Resolution - Device screen size
- Viewport Size - Browser window size
- Language - Browser language
- Ad Click IDs - If visitor came from ads (gclid, fbclid, etc.)
You don't need to include these in your eventData.
Viewing Custom Event Data
Custom events appear in your dashboard, but the primary value is in the data collection. Here's how to make the most of them:
Event Naming for Insights
Group related events with prefixes:
// Ecommerce events
window.bjTrack.event('ecommerce_product_view', { ... });
window.bjTrack.event('ecommerce_add_to_cart', { ... });
window.bjTrack.event('ecommerce_purchase', { ... });
// Engagement events
window.bjTrack.event('engagement_scroll_50', { ... });
window.bjTrack.event('engagement_time_30s', { ... });
window.bjTrack.event('engagement_share', { ... });This makes it easier to:
- Filter and analyze related events
- Build conversion funnels
- Spot patterns
Advanced Patterns
Conversion Funnels
Track a multi-step process:
// Step 1: View pricing
window.bjTrack.event('funnel_pricing_viewed');
// Step 2: Select plan
window.bjTrack.event('funnel_plan_selected', { plan: 'pro' });
// Step 3: Start checkout
window.bjTrack.event('funnel_checkout_started', { plan: 'pro' });
// Step 4: Complete purchase
window.bjTrack.event('funnel_purchase_completed', {
plan: 'pro',
amount: 99,
order_id: 'ORD-12345'
});A/B Test Tracking
Track which variation a user sees:
const variant = Math.random() > 0.5 ? 'A' : 'B';
window.bjTrack.event('ab_test_variant_shown', {
test_name: 'homepage_hero',
variant: variant
});
// Later, track conversion
window.bjTrack.event('ab_test_conversion', {
test_name: 'homepage_hero',
variant: variant,
action: 'signup'
});Error Tracking
Track JavaScript errors:
window.addEventListener('error', (e) => {
window.bjTrack.event('javascript_error', {
message: e.message,
filename: e.filename,
line: e.lineno,
column: e.colno
});
});Technical Details
Event Type
Custom events are tracked with eventType: 2 in our system. This differentiates them from:
eventType: 1- PageviewseventType: 3- Heartbeats (session tracking)
Data Limits
- Event Name: Max 50 characters, alphanumeric + underscores only
- Event Data: No strict limit, but keep it reasonable (< 10 properties recommended)
- Property Names: Any valid JSON property name
- Property Values: Strings, numbers, booleans, or simple objects
Async/Non-Blocking
Event tracking is completely asynchronous and won't block your site:
- Uses
navigator.sendBeacon()when available (most modern browsers) - Falls back to async XHR if needed
- Fires reliably even when user navigates away
- No impact on page performance
Helper Functions
Get Current Visitor ID
const visitorId = window.bjTrack.getVisitorId();
console.log('Visitor ID:', visitorId);Get Ad Click IDs
const adIds = window.bjTrack.getAdClickIds();
console.log('Ad Click IDs:', adIds);
// Example output: { gclid: 'abc123', fbclid: 'def456' }##Common Use Cases
SaaS Application
// Feature adoption
window.bjTrack.event('feature_used', { feature: 'export_csv' });
// Onboarding completion
window.bjTrack.event('onboarding_completed', { steps_completed: 5 });
// Subscription upgrade
window.bjTrack.event('subscription_upgraded', {
from_plan: 'starter',
to_plan: 'pro'
});E-Commerce Site
// Product interactions
window.bjTrack.event('product_view', { product_id: 'SKU123', category: 'Electronics' });
window.bjTrack.event('product_added_to_wishlist', { product_id: 'SKU123' });
window.bjTrack.event('coupon_applied', { code: 'SAVE20', discount: 20 });
// Checkout milestones
window.bjTrack.event('checkout_shipping_completed');
window.bjTrack.event('checkout_payment_completed');
window.bjTrack.event('order_completed', { order_total: 299.99, items: 3 });Content Site
// Engagement
window.bjTrack.event('article_reading_time', { seconds: 120 });
window.bjTrack.event('newsletter_signup', { source: 'sidebar_widget' });
window.bjTrack.event('social_share', { platform: 'twitter', article_id: 'post-123' });
// Content interaction
window.bjTrack.event('comment_posted', { article_id: 'post-123' });
window.bjTrack.event('related_article_clicked', { from: 'post-123', to: 'post-456' });Troubleshooting
Events Not Showing Up
Check:
- Tracking script is installed and loaded
- Event name follows rules (alphanumeric + underscores, max 50 chars)
- No JavaScript errors in console (F12)
- Network tab shows POST requests to analytics endpoint
- Ad blockers disabled (for testing)
Events Firing Multiple Times
Common causes:
- Event listener added multiple times
- Page re-renders in single-page apps
- Use event delegation or check if listener already exists
Fix example:
// Bad - adds listener every render
button.addEventListener('click', () => window.bjTrack.event('click'));
// Good - add listener once
if (!button.dataset.tracked) {
button.addEventListener('click', () => window.bjTrack.event('click'));
button.dataset.tracked = 'true';
}Next Steps
- Real-Time Analytics - See events as they happen
- Getting Started - Complete setup guide
- Visitor Tracking - Understand visitor behavior