Custom Tracking Examples
Example 1: Tracking Add to Cart (WooCommerce)
This example shows how to track WooCommerce add-to-cart interactions. Understanding which products visitors add to their cart (even if they don't complete purchase) helps you personalise product recommendations and identify purchase intent.
JavaScript Tracking
// Add inline JS which records a Add to Cart Event on any button with 'add_to_cart_button' class.
add_action('wp_footer', function () {
?>
<script>
document.addEventListener('click', function(event) {
let button = event.target.closest('button');
// The class 'add_to_cart_button' is used by WooCommerce for all generated add item to cart buttons.
if (!button || !button.classList.contains('add_to_cart_button')) {
return;
}
if (window?.PersonalizeWP?.tracking?.trackEvent) {
let cartArgs = {
'label': button.getAttribute('aria-label'),
};
if (window.pwpTrack?.obj) {
cartArgs.object = window.pwpTrack.obj;
}
if (window.pwpTrack?.type) {
cartArgs['object-type'] = window.pwpTrack.type;
}
window.PersonalizeWP.tracking.trackEvent('add-to-cart', cartArgs);
}
});
</script>
<?php
});
PHP Registration and Display
$personalizewp = personalizewp();
$personalizewp->register_event_type(
'add-to-cart',
array(
'label' => 'Add to cart',
)
);
// Populate the 'Event Value' column cell for Add to Cart Events
add_filter( 'personalizewp_activity_table_event_value_add-to-cart', function ($link_title, $link, $title, $item) {
$button = Activity::get_metadata( $item['ID'], 'label', true );
$obj_id = Activity::get_metadata( $item['ID'], 'object', true );
if ( ! empty( $obj_id ) ) {
$title = get_the_title( $obj_id );
$link = get_edit_post_link( $obj_id );
return sprintf(
'`%1$s` clicked on <a href="%3$s" aria-label="%4$s">%2$s</a>',
esc_html( $button ),
esc_html( $title ),
esc_url( $link ),
esc_attr(
sprintf(
'Edit “%s”',
$title
)
)
);
}
return sprintf(
'`%1$s` clicked on `%2$s`',
esc_html( $button ),
esc_html( $item['url'] ),
);
}, 10, 4 );
Use cases for add-to-cart tracking:
- Identify high-intent visitors who add products but don't complete checkout
- Build segments of visitors interested in specific product categories
- Personalise homepage to show related products based on cart history
- Trigger abandoned cart campaigns based on PersonalizeWP visitor profiles
Example 2: Tracking Video Plays
This example tracks when visitors play HTML5 embedded videos. Video engagement is a strong indicator of interest and can be used to personalise follow-up content or identify high-intent visitors.
JavaScript Implementation
This example demonstrates using the pwp-tracking:ready event for more reliable timing control:
// Add inline JS which records a Play Video Event on any HTML5 embedded video.
add_action('wp_footer', function () {
?>
<script>
// Wait for the PWP Tracking module to emit that it is ready
document.addEventListener('pwp-tracking:ready', function(event) {
// Get all embedded videos
let videos = document.querySelectorAll('video');
videos.forEach((video) => {
// On each hook onto their 'play' event. This event does not bubble up the DOM. See https://developer.mozilla.org/en-US/docs/Web/API/HTMLMediaElement/play_event
video.addEventListener('play', function(e) {
if (window?.PersonalizeWP?.tracking?.trackEvent) {
let videoArgs = {
// Track the source and the duration of the video.
'video-src': video.src,
'video-duration': video.duration || 0
};
if (window.pwpTrack?.obj) {
videoArgs.object = window.pwpTrack.obj;
}
if (window.pwpTrack?.type) {
videoArgs['object-type'] = window.pwpTrack.type;
}
window.PersonalizeWP.tracking.trackEvent('play-video', videoArgs);
}
});
});
}, { once: true });
</script>
<?php
});
Using pwp-tracking:ready event:
The pwp-tracking:ready event fires once PersonalizeWP has fully loaded and initialized its tracking module, including the visitor UUID. This is more reliable than optional chaining when you need to guarantee PersonalizeWP is ready before running your tracking code.
The { once: true } option ensures the event listener only fires once, preventing duplicate video tracking if the event fires multiple times.
PHP Registration and Display
$personalizewp = personalizewp();
$personalizewp->register_event_type(
'play-video',
array(
'label' => 'Video play',
)
);
// Format how video play events appear in the admin
add_filter(
'personalizewp_activity_table_event_value_play-video',
function ($link_title, $link, $title, $item) {
$video_src = Activity::get_metadata( $item['ID'], 'video-src', true );
$duration = Activity::get_metadata( $item['ID'], 'video-duration', true );
$obj_id = Activity::get_metadata( $item['ID'], 'object', true );
$duration_text = $duration ? ' (' . round($duration) . 's)' : '';
if ( ! empty( $obj_id ) ) {
$title = get_the_title( $obj_id );
$link = get_edit_post_link( $obj_id );
return sprintf(
'Video played%1$s on <a href="%3$s" aria-label="%4$s">%2$s</a>',
esc_html( $duration_text ),
esc_html( $title ),
esc_url( $link ),
esc_attr( sprintf( 'Edit “%s”', $title ) )
);
}
return sprintf(
'Video played%1$s on `%2$s`',
esc_html( $duration_text ),
esc_html( $item['url'] )
);
},
10,
4
);
Best Practices
Follow these best practices for event tracking setup.
Event Naming Conventions
Choose clear, consistent event names that describe the action:
- Good:
video-play,form-submit,cta-click,product-view - Avoid:
event1,custom,track,data
Use the same naming convention across your site. Consider prefixing related events (e.g., video-play , video-pause , video-complete ).
What to Track
Focus on tracking actions that indicate:
- Intent signals - Actions that suggest purchase or conversion intent (add to cart, pricing page view, demo request)
- Engagement depth - How deeply visitors engage with content (video plays, scroll depth, time on interactive elements)
- Feature usage - Which features or sections visitors interact with most
- Journey stages - Actions that indicate progression through a journey (calculator usage, comparison tool interaction)
Performance Considerations
- Event delegation - Use event delegation on the document rather than individual elements to reduce memory usage
- Debouncing - For high-frequency events (scroll, mousemove), consider debouncing to avoid overwhelming the tracking API
- Selective tracking - Don't track everything; focus on meaningful interactions that inform personalization or analysis
Data Quality
- Consistent metadata - Use consistent keys across similar event types (e.g., always use
product-idrather than mixingproduct-idandproductId) - Meaningful values - Store human-readable values alongside IDs where helpful (e.g., both
product-id: 123andproduct-name: "Premium Widget") - Context preservation - Include page context (
object,object-type) to understand where events occurred
Security & Privacy
- No sensitive data - Never track passwords, credit card numbers, or personally identifiable information in event metadata
- Respect privacy settings - Check consent status before tracking events if required by your privacy policy
- Data minimization - Only track data you'll actually use for personalization or analysis