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:
Event Name
Event Name + Data
Page View Object
Custom Function
No Arguments
Track a simple event with just a name: umami . track ( eventName : string ): Promise < string >
Example: umami . track ( 'button-click' );
Track an event with custom data: umami . track ( eventName : string , eventData : EventData ): Promise < string >
Example: umami . track ( 'signup' , {
plan: 'premium' ,
referral: 'google'
});
Track a custom page view with all properties: umami . track ( properties : PageViewProperties ): Promise < string >
Example: umami . track ({
website: 'e676c9b4-11e4-4ef1-a4d7-87001773e9f2' ,
url: '/home' ,
title: 'Home page'
});
Use a function for dynamic tracking: umami . track ( eventFunction : ( props ) => EventProperties ): Promise < string >
Example: umami . track ( props => ({
... props ,
name: 'signup' ,
data: { plan: 'premium' }
}));
Track a page view manually: umami . track (): Promise < string >
Example:
Common Use Cases
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 ();
}
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 > ;
}
Use umami.track() in methods: < template >
< button @ click = " handleSignup " > Sign Up </ button >
</ template >
< script >
export default {
methods: {
handleSignup () {
window . umami . track ( 'signup-click' , {
source: 'homepage'
});
}
}
}
</ script >
Create a service for tracking: import { Injectable } from '@angular/core' ;
declare global {
interface Window {
umami : any ;
}
}
@ Injectable ({ providedIn: 'root' })
export class AnalyticsService {
track ( eventName : string , data ?: any ) {
if ( window . umami ) {
window . umami . track ( eventName , data );
}
}
}
Use in components: export class AppComponent {
constructor ( private analytics : AnalyticsService ) {}
onSignup () {
this . analytics . track ( 'signup-click' , {
source: 'homepage'
});
}
}
Use umami.track() in event handlers: < script >
function handleSignup () {
window . umami . track ( 'signup-click' , {
source: 'homepage'
});
}
</ script >
< button on : click = { handleSignup } >
Sign Up
</ button >
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
Check if umami exists
Always verify the tracker is loaded before calling track(): if ( window . umami ) {
umami . track ( 'my-event' );
}
Use descriptive event names
Choose clear, consistent names: // Good
umami . track ( 'newsletter-subscribe' );
umami . track ( 'product-view' );
// Avoid
umami . track ( 'click' );
umami . track ( 'event1' );
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'
});
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