Custom Events

Track specific user interactions beyond basic page views.

Basic Usage

Track any interaction with the klar.track() method:

klar.track('button_click');

Track with properties:

klar.track('button_click', {
  button: 'signup',
  location: 'header'
});

Common Use Cases

Button Clicks

// Track signup button
document.querySelector('.signup-btn').addEventListener('click', () => {
  klar.track('button_click', {
    button: 'signup',
    location: 'hero'
  });
});

Form Submissions

document.querySelector('form').addEventListener('submit', (e) => {
  klar.track('form_submit', {
    form: 'contact',
    fields: Array.from(e.target.elements).map(el => el.name)
  });
});

Purchases

klar.track('purchase', {
  product: 'Pro Plan',
  price: 29,
  currency: 'USD',
  order_id: 'order_123'
});

Video Events

// Track video plays
const video = document.querySelector('video');
video.addEventListener('play', () => {
  klar.track('video_play', {
    video_id: 'intro_video',
    duration: video.duration
  });
});

Search

searchInput.addEventListener('change', (e) => {
  klar.track('search', {
    query: e.target.value,
    results: searchResults.length
  });
});

Event Properties

Add context to your events with properties:

klar.track('event_name', {
  // Strings
  category: 'engagement',
  label: 'signup_button',
  
  // Numbers
  value: 29,
  quantity: 1,
  
  // Booleans
  is_new_user: true,
  
  // Arrays
  tags: ['premium', 'trial']
});

Goal Conversions and Conversion Rate

A goal turns a pageview path or an event into a conversion. The Goals card on your dashboard shows, for every goal, the conversions and the number the rate is divided by.

  • Every completion counts, nothing is deduplicated. Each matching beacon adds one conversion, so a visitor who reaches a goal twice is counted twice. Klar sets no cookie, so it cannot tell a returning visitor from a new one beyond the daily hash.
  • Rate = conversions divided by pageviews. The denominator is the number of pageviews in the same period, shown under each rate as "of N pageviews". An event goal can therefore exceed 100% when one page fires it several times.
  • Filters apply to both numbers. A page filter narrows the conversions by their path. Any other filter (source, country, device, browser, campaign) keeps the conversions of the sessions that match it, and the same filter narrows the pageviews. Conversions recorded before filters were supported carry no session and drop out of a non-page filter.

React Integration

import { useEffect } from 'react';

function SignupButton() {
  const handleClick = () => {
    klar.track('button_click', {
      button: 'signup',
      location: 'header'
    });
    // ... signup logic
  };

  return (
    <button onClick={handleClick}>
      Sign Up
    </button>
  );
}

Vue Integration

<template>
  <button @click="trackClick">Sign Up</button>
</template>

<script setup>
function trackClick() {
  klar.track('button_click', {
    button: 'signup',
    location: 'hero'
  });
}
</script>

Property Limits

  • Maximum 50 properties per event
  • Property names: maximum 64 characters
  • Property values: maximum 256 characters
  • An event over a limit is rejected with 400 and a JSON body { error, code, property }, where code is too_many_properties, property_name_too_long or property_value_too_long. Nothing is stored or truncated.
  • Nested objects are flattened

Funnels

Funnels match steps on the visitor, not on a 30-minute session. A funnel converts when the same visitor completes its steps in order within one visitor-id day, however many visits that takes.

The visitor id is a salted hash that rotates every UTC day, and Klar stores nothing on the device. So funnels cannot link journeys across days: someone who starts on Monday and finishes on Tuesday is counted as a drop-off. Nothing new is stored to make funnels work.