Skip to main content
While HTML attributes are great for tracking clicks, sometimes you need more control. The umami.track() function allows you to track events programmatically from your JavaScript code.

The track() Function

The Umami tracker exposes a global umami object with a track() function:
umami.track(eventName, eventData);
The umami object is automatically available on window after the tracking script loads.

Basic Usage

Track an Event by Name

The simplest way to track an event is by passing an event name:
umami.track('signup-button');
Event names will be truncated past 50 characters.

Track an Event with Data

Attach custom data to your events:
umami.track('purchase', {
  product: 'Pro Plan',
  price: 29.99,
  currency: 'USD'
});

Function Signatures

The track() function accepts multiple signatures for different use cases:
Track a simple event with just a name:
umami.track(eventName: string): Promise<string>
Example:
umami.track('button-click');

Common Use Cases

Form Submissions

Track form submissions with form data:
function handleSubmit(event) {
  event.preventDefault();
  
  const formData = new FormData(event.target);
  
  umami.track('form-submit', {
    formName: 'contact',
    email: formData.get('email'),
    topic: formData.get('topic')
  });
  
  // Submit the form
  event.target.submit();
}

Button Clicks

Track button clicks with contextual information:
document.querySelector('#checkout-btn').addEventListener('click', () => {
  umami.track('checkout-started', {
    cart_value: 149.99,
    item_count: 3,
    has_coupon: true
  });
});

API Responses

Track API calls and their outcomes:
async function fetchUserData() {
  try {
    const response = await fetch('/api/user');
    const data = await response.json();
    
    umami.track('api-call', {
      endpoint: '/api/user',
      status: response.status,
      success: true
    });
    
    return data;
  } catch (error) {
    umami.track('api-call', {
      endpoint: '/api/user',
      success: false,
      error: error.message
    });
    
    throw error;
  }
}

Video Players

Track video interactions:
const video = document.querySelector('#my-video');

video.addEventListener('play', () => {
  umami.track('video-play', {
    video_id: 'product-demo',
    duration: video.duration
  });
});

video.addEventListener('ended', () => {
  umami.track('video-complete', {
    video_id: 'product-demo',
    watch_time: video.currentTime
  });
});

Search Queries

Track user searches:
function handleSearch(query) {
  umami.track('search', {
    query: query,
    results_count: results.length,
    has_filters: filters.length > 0
  });
}

Framework Integration

Use umami.track() in event handlers:
function SignupButton() {
  const handleClick = () => {
    umami.track('signup-click', {
      source: 'homepage',
      timestamp: Date.now()
    });
  };
  
  return (
    <button onClick={handleClick}>
      Sign Up
    </button>
  );
}
Track in useEffect:
import { useEffect } from 'react';

function Dashboard() {
  useEffect(() => {
    umami.track('dashboard-view', {
      user_type: 'premium'
    });
  }, []);
  
  return <div>Dashboard</div>;
}

Advanced Tracking

Track with Function

Use a function to access default properties and customize the payload:
umami.track(props => ({
  ...props,
  name: 'custom-event',
  data: {
    custom_field: 'value',
    timestamp: Date.now()
  }
}));
The props parameter contains default properties: website, hostname, language, referrer, screen, title, and url.

Track Custom Page Views

Manually track page views in single-page applications:
// In your router
router.afterEach((to, from) => {
  umami.track({
    website: 'e676c9b4-11e4-4ef1-a4d7-87001773e9f2',
    url: to.path,
    title: to.meta.title || document.title
  });
});

Conditional Tracking

Track events based on conditions:
function trackPurchase(order) {
  // Only track high-value orders
  if (order.total > 100) {
    umami.track('high-value-purchase', {
      total: order.total,
      items: order.items.length,
      payment_method: order.payment
    });
  }
}

Best Practices

1

Check if umami exists

Always verify the tracker is loaded before calling track():
if (window.umami) {
  umami.track('my-event');
}
2

Use descriptive event names

Choose clear, consistent names:
// Good
umami.track('newsletter-subscribe');
umami.track('product-view');

// Avoid
umami.track('click');
umami.track('event1');
3

Structure your event data

Keep event data organized and meaningful:
umami.track('purchase', {
  product_id: '123',
  product_name: 'Pro Plan',
  category: 'subscription',
  price: 29.99,
  currency: 'USD'
});
4

Handle async operations

The track() function returns a Promise:
await umami.track('critical-event');
// Continue after tracking completes
Event names are truncated at 50 characters. Keep names concise to avoid data loss.

Next Steps

Event Data

Learn about event data structure and limitations

Tracker Functions

Explore all available tracker functions

Build docs developers (and LLMs) love