How to implement custom event tracking in Matomo. Covers event naming conventions, required and optional parameters, ecommerce events, debugging with.
Overview
Event tracking in Matomo captures user interactions beyond pageviews, providing granular insight into how visitors engage with your content. Matomo uses a Category/Action/Name model that allows flexible organization of event data while maintaining consistency for reporting.
Event Model Structure
Core Parameters
| Parameter |
Description |
Example |
Required |
| Category |
High-level grouping |
Video, Form, Navigation |
Yes |
| Action |
Specific interaction type |
play, submit, click |
Yes |
| Name |
Identifier for the element |
homepage_hero_video, newsletter_signup |
Recommended |
| Value |
Numeric value for aggregation |
30 (seconds watched) |
Optional |
Basic Implementation
// Direct tracking API
_paq.push(['trackEvent', 'Video', 'Play', 'Product Demo', 45]);
// Via Matomo Tag Manager data layer
_mtm.push({
'event': 'videoPlay',
'eventCategory': 'Video',
'eventAction': 'Play',
'eventName': 'Product Demo',
'eventValue': 45
});
Core Events to Implement
Navigation and Engagement
| Event |
Category |
Action |
Name |
Value |
| Page scroll depth |
Engagement |
scroll |
25%, 50%, 75%, 100% |
Percentage |
| Time on page milestones |
Engagement |
time_spent |
Page title |
Seconds |
| Outbound link clicks |
Navigation |
outbound_click |
Destination URL |
- |
| File downloads |
Downloads |
download |
File name |
File size (KB) |
| Internal link clicks |
Navigation |
internal_click |
Link text or ID |
- |
Video Tracking
| Event |
Category |
Action |
Name |
Value |
| Video start |
Video |
play |
Video title |
- |
| Video progress |
Video |
progress |
Video title |
25, 50, 75 |
| Video complete |
Video |
complete |
Video title |
Duration |
| Video pause |
Video |
pause |
Video title |
Current position |
| Event |
Category |
Action |
Name |
Value |
| Form start |
Form |
start |
Form name |
- |
| Field focus |
Form |
field_focus |
Field name |
- |
| Form submit success |
Form |
submit_success |
Form name |
Fields completed |
| Form submit error |
Form |
submit_error |
Form name |
Error count |
| Form abandonment |
Form |
abandon |
Form name |
Last field |
Search Behavior
| Event |
Category |
Action |
Name |
Value |
| Site search |
Search |
query |
Search term |
Results count |
| Search refinement |
Search |
refine |
Filter applied |
- |
| Search result click |
Search |
result_click |
Clicked item |
Position |
| Zero results |
Search |
no_results |
Search term |
- |
Ecommerce Event Tracking
Product Interactions
// Product view
_paq.push(['setEcommerceView',
'SKU-12345', // Product SKU
'Wireless Headphones', // Product name
'Electronics/Audio', // Category
79.99 // Price
]);
_paq.push(['trackPageView']);
Cart Operations
// Add to cart
_paq.push(['addEcommerceItem',
'SKU-12345', // SKU
'Wireless Headphones', // Name
'Electronics/Audio', // Category
79.99, // Price
1 // Quantity
]);
_paq.push(['trackEcommerceCartUpdate', 79.99]); // Cart total
Order Completion
// Track order
_paq.push(['addEcommerceItem', 'SKU-12345', 'Wireless Headphones', 'Electronics', 79.99, 1]);
_paq.push(['addEcommerceItem', 'SKU-67890', 'USB-C Cable', 'Accessories', 12.99, 2]);
_paq.push(['trackEcommerceOrder',
'ORD-98765', // Order ID
105.97, // Grand total
92.98, // Subtotal
6.40, // Tax
5.99, // Shipping
10.00 // Discount
]);
Content Tracking
Matomo can automatically track visibility and interaction with content blocks:
<!-- Automatic content tracking -->
<div data-track-content data-content-name="Promo Banner">
<a href="/sale" data-content-piece="Summer Sale" data-content-target="/sale">
<img src="banner.jpg" />
</a>
</div>
Enable in your Matomo configuration:
_paq.push(['trackVisibleContentImpressions']);
_paq.push(['trackContentInteraction', 'click', 'Promo Banner', 'Summer Sale', '/sale']);
Custom Dimensions with Events
Attach additional context to events using custom dimensions:
_paq.push(['setCustomDimension', 1, 'premium']); // Customer tier
_paq.push(['setCustomDimension', 2, 'variant_a']); // A/B test
_paq.push(['trackEvent', 'CTA', 'click', 'upgrade_button']);
For action-scoped dimensions (reset after each event):
_paq.push(['trackEvent', 'Form', 'submit', 'contact_form', null, {
dimension3: 'organic' // Traffic source at conversion
}]);
Naming Conventions
Category Standards
- Use PascalCase or snake_case consistently
- Keep categories broad for effective grouping (10-20 max)
- Examples:
Video, Form, Navigation, Ecommerce, Search
Action Standards
- Use lowercase with underscores
- Describe the interaction type:
click, submit, play, scroll
- Keep actions reusable across categories
Name Standards
- Be specific enough to identify the element
- Include location context where relevant:
header_cta, footer_newsletter
- Avoid dynamic values that create cardinality issues
Event Payload Rules
Required Data
visitorId: Ensure the Matomo visitor cookie is present
userId: Include for authenticated users for cross-device tracking
consent: Respect user consent preferences before firing events
Value Guidelines
- Use numeric values for metrics that should aggregate (time, counts, currency)
- Values must be positive integers or floats
- Omit value if the event doesn't have a meaningful numeric component
QA and Validation
Pre-Launch Checklist
- Real-Time dashboard: Verify events appear within seconds of triggering
- Event report: Confirm Category/Action/Name hierarchy is correct
- Custom dimensions: Check dimension values attach to events properly
- Ecommerce reports: Validate product SKUs, prices, and order totals
// Enable debug mode
_paq.push(['enableLinkTracking']);
_paq.push(['setRequestMethod', 'POST']);
// Log all tracking calls
_paq.push(['setCustomRequestProcessing', function(request) {
console.log('Matomo Request:', request);
}]);
Common Validation Points
| Check |
Expected Result |
| Event fires once per interaction |
No duplicate events in Real-Time |
| Category/Action/Name populated |
All three fields visible in reports |
| Ecommerce totals match |
Order revenue matches checkout value |
| Custom dimensions attached |
Dimension values appear in event details |
| Consent respected |
No events fire before consent granted |
Troubleshooting
| Symptom |
Cause |
Solution |
| Events not appearing |
Tracker blocked |
Check ad blockers, CSP headers |
| Duplicate events |
Multiple trackers or bindings |
Audit event listener attachments |
| Missing event names |
Name parameter empty |
Ensure name is passed in tracking call |
| Incorrect values |
Type mismatch |
Values must be numeric |
| Events without pageview |
Tracker not initialized |
Ensure trackPageView fires first |