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 &#8220;%s&#8221;',
                    $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 &#8220;%s&#8221;', $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-id    rather than mixing product-id    and productId   )
  • Meaningful values - Store human-readable values alongside IDs where helpful (e.g., both product-id: 123    and product-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

Still need help? Contact Us Contact Us