WordPress Integration
Add privacy-focused analytics to your WordPress site. Track visitors, understand behaviour, and grow your audience without compromising privacy.
Manual setup only. Zenovay does not currently provide an official WordPress plugin or WooCommerce extension. The instructions below use the standard tracking script with snippets in header.php / functions.php, which work reliably on every WordPress install. Wherever you see references to "automatic tracking" below, it means a single add_action() hook that you paste into your theme — not an installable plugin.
Quick Start
| Method | Best For | Setup Time |
|---|---|---|
header.php snippet | Custom themes | 3 minutes |
functions.php hook | Developer-managed sites with admin exclusion | 5 minutes |
wp_enqueue_script | Sites that strictly use WordPress script enqueueing | 5 minutes |
Method 1: Theme Header (Recommended)
Add to your theme's header.php before </head>:
<!-- Zenovay Analytics -->
<script defer data-tracking-code="YOUR_TRACKING_CODE" src="https://api.zenovay.com/z.js"></script>
This is the simplest install. Works on all themes that have a header.php file and the </head> tag visible in the template.
Method 2: functions.php hook
For more control (exclude admin users, conditional loading, etc.), add to your theme's functions.php:
/**
* Add Zenovay Analytics tracking script
*/
function zenovay_tracking_script() {
// Don't track admin users (optional)
if (current_user_can('manage_options')) {
return;
}
?>
<script defer data-tracking-code="YOUR_TRACKING_CODE" src="https://api.zenovay.com/z.js"></script>
<?php
}
add_action('wp_head', 'zenovay_tracking_script');
Method 3: wp_enqueue_script
For proper script management following WordPress conventions:
/**
* Enqueue Zenovay Analytics script
*/
function zenovay_enqueue_scripts() {
if (current_user_can('manage_options')) {
return;
}
wp_enqueue_script(
'zenovay-analytics',
'https://api.zenovay.com/z.js',
array(), // No dependencies
null, // No version (external script)
false // Load in header
);
add_filter('script_loader_tag', function($tag, $handle) {
if ('zenovay-analytics' === $handle) {
return str_replace(' src', ' defer data-tracking-code="YOUR_TRACKING_CODE" src', $tag);
}
return $tag;
}, 10, 2);
}
add_action('wp_enqueue_scripts', 'zenovay_enqueue_scripts');
WooCommerce Tracking
Track product views, add-to-cart, and purchases on your WooCommerce store. Add to your theme's functions.php:
/**
* Zenovay WooCommerce Event Tracking
*/
// Track product views
function zenovay_track_product_view() {
if (!is_product()) return;
global $product;
?>
<script>
document.addEventListener('DOMContentLoaded', function() {
if (window.zenovay) {
window.zenovay('track', 'product_viewed', {
product_id: '<?php echo esc_js($product->get_id()); ?>',
product_name: '<?php echo esc_js($product->get_name()); ?>',
price: <?php echo $product->get_price(); ?>,
currency: '<?php echo get_woocommerce_currency(); ?>',
category: '<?php echo esc_js(wc_get_product_category_list($product->get_id())); ?>'
});
}
});
</script>
<?php
}
add_action('wp_footer', 'zenovay_track_product_view');
// Track add to cart
function zenovay_track_add_to_cart($cart_item_key, $product_id, $quantity) {
$product = wc_get_product($product_id);
?>
<script>
if (window.zenovay) {
window.zenovay('track', 'add_to_cart', {
product_id: '<?php echo esc_js($product_id); ?>',
product_name: '<?php echo esc_js($product->get_name()); ?>',
price: <?php echo $product->get_price(); ?>,
quantity: <?php echo $quantity; ?>,
currency: '<?php echo get_woocommerce_currency(); ?>'
});
}
</script>
<?php
}
add_action('woocommerce_add_to_cart', 'zenovay_track_add_to_cart', 10, 3);
// Track purchases on thank you page
function zenovay_track_purchase($order_id) {
$order = wc_get_order($order_id);
if (!$order) return;
// Only track once
if ($order->get_meta('_zenovay_tracked')) return;
$order->update_meta_data('_zenovay_tracked', true);
$order->save();
$items = array();
foreach ($order->get_items() as $item) {
$items[] = array(
'product_id' => $item->get_product_id(),
'name' => $item->get_name(),
'price' => $item->get_total(),
'quantity' => $item->get_quantity()
);
}
?>
<script>
document.addEventListener('DOMContentLoaded', function() {
if (window.zenovay) {
window.zenovay('track', 'purchase', {
transaction_id: '<?php echo esc_js($order->get_order_number()); ?>',
revenue: <?php echo $order->get_total(); ?>,
currency: '<?php echo $order->get_currency(); ?>',
tax: <?php echo $order->get_total_tax(); ?>,
shipping: <?php echo $order->get_shipping_total(); ?>,
items: <?php echo json_encode($items); ?>
});
}
});
</script>
<?php
}
add_action('woocommerce_thankyou', 'zenovay_track_purchase');
Contact Form Tracking
Contact Form 7
function zenovay_track_cf7_submission($contact_form, $result) {
if ($result['status'] !== 'mail_sent') return;
?>
<script>
if (window.zenovay) {
window.zenovay('track', 'form_submitted', {
form_id: '<?php echo esc_js($contact_form->id()); ?>',
form_name: '<?php echo esc_js($contact_form->title()); ?>'
});
}
</script>
<?php
}
add_action('wpcf7_mail_sent', 'zenovay_track_cf7_submission', 10, 2);
Or use the JavaScript event:
document.addEventListener('wpcf7mailsent', function(event) {
if (window.zenovay) {
window.zenovay('track', 'form_submitted', {
form_id: event.detail.contactFormId,
});
}
});
Gravity Forms
function zenovay_track_gf_submission($entry, $form) {
?>
<script>
if (window.zenovay) {
window.zenovay('track', 'form_submitted', {
form_id: '<?php echo esc_js($form['id']); ?>',
form_name: '<?php echo esc_js($form['title']); ?>'
});
}
</script>
<?php
}
add_action('gform_after_submission', 'zenovay_track_gf_submission', 10, 2);
WPForms
function zenovay_track_wpforms_submission($fields, $entry, $form_data) {
?>
<script>
if (window.zenovay) {
window.zenovay('track', 'form_submitted', {
form_id: '<?php echo esc_js($form_data['id']); ?>',
form_name: '<?php echo esc_js($form_data['settings']['form_title']); ?>'
});
}
</script>
<?php
}
add_action('wpforms_process_complete', 'zenovay_track_wpforms_submission', 10, 3);
Identify logged-in users
Identify WordPress users for cross-session tracking:
function zenovay_identify_user() {
if (!is_user_logged_in()) return;
$user = wp_get_current_user();
?>
<script>
document.addEventListener('DOMContentLoaded', function() {
if (window.zenovay) {
window.zenovay('identify', {
userId: '<?php echo esc_js($user->ID); ?>',
email: '<?php echo esc_js($user->user_email); ?>',
name: '<?php echo esc_js($user->display_name); ?>'
});
}
});
</script>
<?php
}
add_action('wp_footer', 'zenovay_identify_user');
First-Party Tracking Setup
Bypass ad blockers by proxying through your domain. See the First-Party Tracking Guide for the cross-platform setup. WordPress-specific rewrite rules:
/**
* Add rewrite rules for Zenovay first-party proxy
*/
function zenovay_add_rewrite_rules() {
add_rewrite_rule('^_z/script\.js$', 'index.php?zenovay_proxy=script', 'top');
add_rewrite_rule('^_z/event$', 'index.php?zenovay_proxy=event', 'top');
}
add_action('init', 'zenovay_add_rewrite_rules');
function zenovay_query_vars($vars) {
$vars[] = 'zenovay_proxy';
return $vars;
}
add_filter('query_vars', 'zenovay_query_vars');
function zenovay_proxy_handler() {
$proxy = get_query_var('zenovay_proxy');
if (!$proxy) return;
if ($proxy === 'script') {
header('Content-Type: application/javascript');
echo file_get_contents('https://api.zenovay.com/z.js');
exit;
}
if ($proxy === 'event') {
$response = wp_remote_post('https://api.zenovay.com/e/' . $_GET['tracking_code'], [
'body' => file_get_contents('php://input'),
'headers' => ['Content-Type' => 'application/json']
]);
header('Content-Type: application/json');
echo wp_remote_retrieve_body($response);
exit;
}
}
add_action('template_redirect', 'zenovay_proxy_handler');
Then update your tracking script to use the proxy:
<script defer
data-tracking-code="YOUR_TRACKING_CODE"
data-api-url="/_z/"
src="/_z/script.js">
</script>
After adding the rewrite rules, go to Settings → Permalinks and click Save Changes to flush the rewrite cache.
Cache Plugin Compatibility
Exclude the Zenovay first-party routes from your cache plugin so events post through correctly.
WP Super Cache
Add to wp-content/wp-cache-config.php:
$cache_rejected_uri = array(
'/_z/',
);
W3 Total Cache
Go to Performance → Page Cache and add /_z/ to Never cache the following pages.
LiteSpeed Cache
LiteSpeed Cache → Cache → Excludes → Do Not Cache URIs:
/_z/
WP Rocket
Settings → WP Rocket → Advanced Rules → Never Cache URL(s):
/_z/(.*)
WP Fastest Cache
WP Fastest Cache → Exclude → Exclude Pages — add /_z/.
Multisite Configuration
For WordPress Multisite networks, the tracking script lives in your theme's header.php or functions.php and works per-site as configured. To use a single tracking code across the whole network:
/**
* Use a single tracking code across the multisite network
*/
function zenovay_network_tracking_code() {
return 'YOUR_NETWORK_TRACKING_CODE';
}
add_filter('zenovay_tracking_code', 'zenovay_network_tracking_code');
Otherwise, configure a different tracking code per site by hardcoding it in each site's theme.
Performance Notes
The Zenovay tracker is:
- Deferred — doesn't block page rendering
- Lightweight — < 23 KB gzipped
- CDN-delivered — globally cached at the edge
Conditional Loading
Skip tracking on specific pages:
function zenovay_conditional_loading() {
if (is_admin()) return;
if (is_page(array('privacy-policy', 'terms'))) return;
?>
<script defer data-tracking-code="YOUR_TRACKING_CODE" src="https://api.zenovay.com/z.js"></script>
<?php
}
add_action('wp_head', 'zenovay_conditional_loading');
Troubleshooting
Script not loading
- View the page source (Cmd/Ctrl+U) and look for
<script defer data-tracking-code=...>between<head>and</head> - Verify your tracking code matches the value in the Zenovay dashboard
- Open the browser console and check for JavaScript errors
- Temporarily disable caching to test
- Check whether a security plugin (Wordfence, iThemes Security, etc.) is blocking external scripts to
api.zenovay.com
Duplicate page views
- Make sure you added the snippet only once (don't paste in both
header.phpAND afunctions.phphook) - Check for AJAX-loaded content re-triggering tracking
- Review caching plugin configuration
WooCommerce purchases missing
- Verify the snippet loads on the thank-you page
- Check the WooCommerce checkout flow (multi-page vs single-page) — some checkouts skip the standard
woocommerce_thankyouhook - Make sure jQuery compatibility mode isn't interfering
Caching issues
- Exclude
/_z/routes from page cache (see Cache Plugin Compatibility above) - Clear all caches after configuration changes
- Test in incognito/private browsing mode
Security Considerations
Content Security Policy
If your site uses a CSP header, allow Zenovay:
script-src 'self' https://api.zenovay.com;
connect-src 'self' https://api.zenovay.com;
With first-party proxy, only 'self' is needed.
Excluding Sensitive Pages
function zenovay_should_track() {
if (is_admin()) return false;
if (is_page(array('my-account', 'checkout'))) return false;
if (current_user_can('manage_options')) return false;
return true;
}
Privacy Compliance
For cookieless tracking, add data-cookieless="true":
<script defer
data-tracking-code="YOUR_TRACKING_CODE"
data-cookieless="true"
src="https://api.zenovay.com/z.js"></script>
In this mode no cookies or local storage entries are set — visitor IDs live only for the current tab. See the Privacy Compliance Guide for full detail.
Cookie Consent Integration
With popular consent plugins:
// CookieYes — load tracking after consent
document.addEventListener('cookieyes_consent_update', function(e) {
if (e.detail.accepted.includes('analytics')) {
var s = document.createElement('script');
s.defer = true;
s.src = 'https://api.zenovay.com/z.js';
s.dataset.trackingCode = 'YOUR_TRACKING_CODE';
document.head.appendChild(s);
}
});
// Complianz — same pattern
document.addEventListener('cmplz_fire_statistics', function() {
var s = document.createElement('script');
s.defer = true;
s.src = 'https://api.zenovay.com/z.js';
s.dataset.trackingCode = 'YOUR_TRACKING_CODE';
document.head.appendChild(s);
});
See GDPR Compliance Guide for detailed setup.
Related Resources
- First-Party Tracking
- Custom Events
- Conversion Funnels
- GDPR Compliance
- WordPress integration help article
Need help? Contact [email protected] or visit our Help Center.