Skip to main content

Event Filters

Available Since

Version 1.51.0 of the Pixel Manager

Customize event tracking data for all pixels using JavaScript (front-end) and PHP (server-side) filters.

Why Use the Command Queue?

Always wrap your filters in the Pixel Manager command queue:

window._pmwq = window._pmwq || [];
window._pmwq.push(function() {
pmw.hooks.addFilter('pmw_pixel_data_facebook', 'my-plugin', function(pixelData) {
pixelData.custom_data.custom_field = 'my_value';
return pixelData;
});
});

Why? Caching systems and JavaScript optimizers may shuffle, combine, or delay script loading. The command queue provides a 100% reliable way to ensure your filters register after Pixel Manager loads, preventing race conditions and initialization errors. Without it, pmw.hooks may not exist yet, causing your code to fail silently.

Adding to WordPress:

/wp-content/themes/child-theme/functions.php
add_action('wp_head', function() {
?>
<script>
window._pmwq = window._pmwq || [];
window._pmwq.push(function() {
pmw.hooks.addFilter('pmw_pixel_data_facebook', 'my-plugin', function(pixelData) {
pixelData.custom_data.custom_field = 'my_value';
return pixelData;
});
});
</script>
<?php
}, 1); // Priority 1 to load early in <head>

Planning Your Filters

Before implementing filters, consider where your events are processed:

Front-End vs. Server-Side Events

Front-end events (processed in the browser):

  • All events when server-to-server tracking is disabled
  • Events like add_to_cart, view_item, begin_checkout, etc.
  • Purchase events only if processed through the browser

Server-side events (processed on the server):

  • Purchase events when server-to-server tracking is enabled (Facebook CAPI, TikTok EAPI, Pinterest APIC, Snapchat CAPI)
  • Google Analytics purchase events when Measurement Protocol is enabled
  • These are always sent from the server, never through the browser

Why server-side purchase events? Browser-based tracking can be blocked by ad blockers, browser extensions, privacy settings, or network-level filters. When server-to-server tracking is enabled, purchase events are compiled and sent directly from your server to the advertising platforms, completely bypassing the browser. This makes them immune to client-side blocking, ensuring 100% reliable conversion tracking. The tradeoff is that these events are processed in a completely independent pipeline, which means they require separate filters.

Critical: Purchase Events with Server-to-Server Tracking

When server-to-server tracking is active, purchase events are compiled and sent exclusively from the server. This means:

  • Front-end filters will NOT affect these purchase events
  • You must implement PHP server-side filters to modify purchase event data

Example: To filter purchase events with server-to-server tracking enabled, you need both:

// Front-end (for any browser-based purchase events)
window._pmwq.push(function() {
pmw.hooks.addFilter('pmw_event_payload_purchase', 'my-filter', function(payload) {
payload.event_data.custom_field = 'value';
return payload;
});
});
// Server-side (REQUIRED for server-to-server purchase events)
add_filter('pmw_server_event_payload_event_purchase', function($pixel_data, $pixel_name, $event_name) {
$pixel_data['custom_data']['custom_field'] = 'value';
return $pixel_data;
}, 10, 3);

Always implement server-side filters when working with purchase events if you have server-to-server tracking enabled.

Front-End Filters (JavaScript)

Filter Pipeline

Events flow through 4 stages. Each filter must return the modified data:

  1. pmw_event_payload_pre - Before pixel transformations (modify core event data)
  2. pmw_pixel_data_{pixel} - Per-pixel transformations (e.g., pmw_pixel_data_facebook)
  3. pmw_event_payload_{event} - Per-event type (e.g., pmw_event_payload_purchase)
  4. pmw_event_payload_post - Final stage (logging, debugging)

Supported pixels: facebook, google_ads, google_analytics, tiktok, pinterest, snapchat, linkedin, microsoft_ads, twitter, reddit, taboola, outbrain

Supported events: page_view, add_to_cart, view_item, view_item_list, begin_checkout, add_payment_info, add_to_wishlist, search, purchase

API

pmw.hooks.addFilter(hookName, namespace, callback, priority)
pmw.hooks.removeFilter(hookName, namespace)
pmw.hooks.hasFilter(hookName, namespace)
  • namespace - Unique identifier to prevent conflicts (e.g., 'my-plugin/feature')
  • priority - Execution order (default: 10, lower runs first)
  • Return null to block an event from firing

Examples

Add Custom Facebook Parameters

window._pmwq.push(function() {
pmw.hooks.addFilter('pmw_pixel_data_facebook', 'my-store', function(pixelData) {
pixelData.custom_data = pixelData.custom_data || {};
pixelData.custom_data.store_location = 'NYC';
pixelData.custom_data.user_segment = 'premium';
return pixelData;
});
});

Adjust Prices Globally

window._pmwq.push(function() {
pmw.hooks.addFilter('pmw_event_payload_pre', 'price-modifier', function(payload) {
if (payload.event_data?.product?.price) {
payload.event_data.product.price *= 1.15; // +15% markup
}
return payload;
});
});

Filter by Event Type

window._pmwq.push(function() {
pmw.hooks.addFilter('pmw_event_payload_purchase', 'purchase-tags', function(payload) {
if (payload.event_data?.order_total > 500) {
payload.event_data.high_value = true;
}
return payload;
});
});

Block Events Conditionally

window._pmwq.push(function() {
pmw.hooks.addFilter('pmw_pixel_data_facebook', 'admin-filter', function(pixelData) {
if (window.userIsAdmin) {
return null; // Block event
}
return pixelData;
});
});

Use Priority for Execution Order

window._pmwq.push(function() {
// Runs first (priority 5)
pmw.hooks.addFilter('pmw_event_payload_pre', 'early-filter', function(payload) {
payload.event_data.processed_by = ['early-filter'];
return payload;
}, 5);

// Runs second (priority 10)
pmw.hooks.addFilter('pmw_event_payload_pre', 'late-filter', function(payload) {
payload.event_data.processed_by.push('late-filter');
return payload;
}, 10);
});

Server-Side Filters (PHP)

Filter Pipeline

Server-side events (Facebook CAPI, TikTok EAPI, Pinterest APIC, Snapchat CAPI) flow through 5 stages:

  1. pmw_server_event_payload_pre - Before pixel processing (all pixels at once)
  2. pmw_server_event_payload_{pixel} - Per-pixel, all events (e.g., facebook)
  3. pmw_server_event_payload_event_{event} - Per-event, all pixels (e.g., purchase)
  4. pmw_server_event_payload_{pixel}_{event} - Specific pixel + event (e.g., facebook_purchase)
  5. pmw_server_event_payload_post - Final stage before API transmission

Examples

Modify All Purchase Events (All Pixels)

add_filter('pmw_server_event_payload_event_purchase', function($pixel_data, $pixel_name, $event_name) {
// Add timestamp to all purchase events across all pixels
$pixel_data['custom_data']['order_timestamp'] = time();

// Categorize by value
if (isset($pixel_data['custom_data']['value'])) {
$value = $pixel_data['custom_data']['value'];
$pixel_data['custom_data']['value_tier'] = $value < 50 ? 'low' : ($value < 200 ? 'medium' : 'high');
}

return $pixel_data;
}, 10, 3);

Add Custom Data to Facebook Only

add_filter('pmw_server_event_payload_facebook', function($pixel_data, $pixel_name) {
$pixel_data['user_data']['subscription_status'] = 'premium';
return $pixel_data;
}, 10, 2);

Target Specific Pixel + Event

add_filter('pmw_server_event_payload_facebook_purchase', function($pixel_data, $pixel_name, $event_name) {
$user_id = get_current_user_id();
if ($user_id) {
$ltv = get_user_meta($user_id, 'customer_ltv', true);
if ($ltv > 1000 && isset($pixel_data['custom_data']['value'])) {
$pixel_data['custom_data']['value'] *= 1.2; // Boost value for high-LTV customers
}
}
return $pixel_data;
}, 10, 3);

Block Events Conditionally

// Block low-value purchases from all pixels
add_filter('pmw_server_event_payload_event_purchase', function($pixel_data, $pixel_name, $event_name) {
if (isset($pixel_data['custom_data']['value']) && $pixel_data['custom_data']['value'] < 10) {
return null; // Blocks event for all pixels
}
return $pixel_data;
}, 10, 3);

// Block only from Facebook
add_filter('pmw_server_event_payload_facebook', function($pixel_data) {
if (some_condition()) {
return null;
}
return $pixel_data;
});

Event Payload Structure

{
event: 'add_to_cart',
event_data: {
product: {
id: 123,
name: 'Product Name',
price: 99.99,
quantity: 1,
currency: 'USD',
categories: ['Electronics']
}
},
pixels: {
facebook: {
event_name: 'AddToCart',
event_id: 'unique-id',
custom_data: { /* pixel-specific data */ }
},
google_analytics: {
event_name: 'add_to_cart',
event_data: { /* pixel-specific data */ }
}
}
}

Best Practices

  1. Always return the value - Filters must return the modified data or null to block
  2. Use unique namespaces - Format: 'plugin-name/feature' or 'company-name/modifier'
  3. Wrap in _pmwq - Ensures Pixel Manager loads before your filters
  4. Check data exists - Use optional chaining: payload.event_data?.product?.price
  5. Use appropriate priority - Default is 10; lower numbers run first
  6. Test thoroughly - Check browser console for filter execution logs

Debugging

Console Logging

Filter execution is logged to the browser console:

🔍 Pre-processing filter called: add_to_cart
📊 GA pixel data filter called: add_to_cart

Inspect Payloads

window._pmwq.push(function() {
pmw.hooks.addFilter('pmw_event_payload_post', 'debugger', function(payload, eventName) {
console.log(`Event: ${eventName}`, payload);
return payload;
}, 999); // High priority to run last
});

PHP Debugging

add_filter('pmw_server_event_payload_post', function($pixel_data, $pixel_name) {
if (defined('WP_DEBUG') && WP_DEBUG) {
error_log("Sending {$pixel_data['event_name']} to {$pixel_name}: " . json_encode($pixel_data));
}
return $pixel_data;
}, 10, 2);

Migration from Old System

If you were using jQuery event listeners:

Before:

jQuery(document).on("pmw:add-to-cart", function(event, product) {
product.price = product.price * 1.1;
});

After:

window._pmwq.push(function() {
pmw.hooks.addFilter('pmw_event_payload_add_to_cart', 'namespace', function(payload) {
payload.event_data.product.price *= 1.1;
return payload;
});
});

Make more money from your ads with high-precision tracking