Documentation

Custom Events

Track specific user actions beyond pageviews

Overview

By default, Loamly tracks page views and form submissions automatically. Custom events let you track any other user action that matters to your business:

  • Button clicks (CTA, pricing toggle, feature toggles)
  • Video interactions (play, pause, completion)
  • File downloads
  • Tab or section views
  • Calculator or tool usage
  • Chat widget opens
  • Any meaningful interaction

Tracking events

Use the window.loamly.event() method to track custom events:

window.loamly.event('event_name', {
  // optional properties
});

Basic example

// Track a button click
document.querySelector('.pricing-toggle').addEventListener('click', () => {
  window.loamly.event('pricing_toggle_clicked');
});

With properties

// Track with additional context
window.loamly.event('video_played', {
  video_id: 'intro-demo',
  video_title: 'Product Introduction',
  duration: 120
});

Script loading

Always check if window.loamly exists before calling methods, or use optional chaining: window.loamly?.event(...)

Event properties

Event properties provide context and enable filtering in your dashboard:

Property TypeExamples
Stringsbutton_text: "Start Free Trial"
Numbersscroll_depth: 75
Booleansis_mobile: true
Page contextpage: window.location.pathname

Reserved property names

Do not use these reserved names as property keys:

  • timestamp (automatically added)
  • visitor_id (automatically added)
  • session_id (automatically added)
  • page_url (automatically added)

Common examples

CTA button click

document.querySelectorAll('[data-cta]').forEach(button => {
  button.addEventListener('click', () => {
    window.loamly?.event('cta_clicked', {
      cta_text: button.textContent,
      cta_location: button.dataset.cta,
      page: window.location.pathname
    });
  });
});

Video tracking

const video = document.querySelector('video');

video.addEventListener('play', () => {
  window.loamly?.event('video_started', {
    video_src: video.src
  });
});

video.addEventListener('ended', () => {
  window.loamly?.event('video_completed', {
    video_src: video.src,
    duration: video.duration
  });
});

Scroll depth

let maxScroll = 0;
const thresholds = [25, 50, 75, 100];
const tracked = new Set();

window.addEventListener('scroll', () => {
  const scrollPercent = Math.round(
    (window.scrollY / (document.body.scrollHeight - window.innerHeight)) * 100
  );
  
  thresholds.forEach(threshold => {
    if (scrollPercent >= threshold && !tracked.has(threshold)) {
      tracked.add(threshold);
      window.loamly?.event('scroll_depth', {
        depth: threshold,
        page: window.location.pathname
      });
    }
  });
});

Pricing toggle

document.querySelector('.billing-toggle').addEventListener('click', (e) => {
  const isAnnual = e.target.checked;
  window.loamly?.event('pricing_toggle', {
    billing_period: isAnnual ? 'annual' : 'monthly'
  });
});

File download

document.querySelectorAll('a[download]').forEach(link => {
  link.addEventListener('click', () => {
    window.loamly?.event('file_downloaded', {
      file_name: link.download || link.href.split('/').pop(),
      file_url: link.href
    });
  });
});

Best practices

  • Use snake_case for event names. This ensures consistency: button_clicked, not buttonClicked.
  • Be specific but not too granular. Track meaningful actions, not every mouse move.
  • Include context. Add properties that help you understand where and why the event occurred.
  • Document your events. Keep a list of event names and their properties for your team.
  • Test in development. Verify events appear in your dashboard before going to production.

Avoid PII in events

Do not include personally identifiable information (names, emails, phone numbers) in event properties unless you have configured Loamly for PII handling.