WordPress Tracking Issues
Platform-specific guides for diagnosing and fixing analytics and tracking issues on WordPress.
Common Issues Overview
WordPress tracking issues typically stem from plugin conflicts, theme incompatibilities, caching layers, consent management tools, or JavaScript errors. This comprehensive guide addresses the most common scenarios encountered on WordPress sites.
Events Not Firing
Debug why analytics events aren't being captured on WordPress.
Installation Problems
Plugin-Based Installations
Google Analytics Plugins Not Working
Symptoms:
- Plugin installed but no data in GA4
- Measurement ID saved but tracking not active
- Plugin settings page shows errors
Common Causes:
- Duplicate tracking codes - Multiple plugins or manual code conflicting
- Caching issues - Page cache serving old version without tracking code
- Plugin conflicts - Security or performance plugins blocking script execution
- Incorrect Measurement ID format - Using GA3 tracking ID in GA4 field
Solutions:
Check for duplicate installations:
// Add to functions.php temporarily to debug
add_action('wp_footer', function() {
echo '<!-- Tracking Debug -->';
echo '<script>console.log("GA loaded:", typeof gtag);</script>';
echo '<script>console.log("GA4:", typeof window.gtag === "function");</script>';
});
Verify plugin output in page source:
# Check if plugin is outputting code
curl https://yoursite.com | grep -i "gtag\|analytics"
Clear all caches:
- WordPress object cache
- Page cache (WP Rocket, W3 Total Cache, etc.)
- CDN cache (Cloudflare, etc.)
- Browser cache
Tag Manager Plugins Issues
MonsterInsights / ExactMetrics:
- Verify authentication is still active
- Check if site is authorized in GA property
- Review excluded user roles (admins often excluded by default)
- Confirm enhanced ecommerce is enabled for WooCommerce tracking
Site Kit by Google:
- Re-authenticate Google account connection
- Verify Site Kit has proper permissions
- Check if modules are properly activated
- Review Analytics module settings
Google Tag Manager for WordPress (DuracellTomi):
- Confirm GTM container ID is correct (GTM-XXXXXX format)
- Verify container is published
- Check dataLayer output with browser console
- Test with GTM preview mode
Manual Code Installation Problems
Code Not Appearing in Source
Check these common issues:
- Wrong hook priority:
// May not execute if priority too low
add_action('wp_head', 'my_tracking_code', 999); // Try higher priority
- Theme not calling wp_head():
// In header.php, verify this exists before </head>
<?php wp_head(); ?>
- Code in wrong location:
// Tracking code should be in wp_head, not wp_footer for most platforms
function add_analytics_code() {
?>
<!-- Google tag (gtag.js) -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-XXXXXXXXXX');
</script>
<?php
}
add_action('wp_head', 'add_analytics_code', 1);
- Functions.php in wrong theme:
- Check child theme vs parent theme
- Verify active theme's functions.php is being used
Code Appearing But Not Executing
JavaScript errors preventing execution:
Check browser console for:
- Syntax errors in tracking code
- Conflicts with jQuery or other libraries
- Security policies blocking script execution
- Content Security Policy (CSP) violations
Debug with:
// Add to tracking code temporarily
console.log('Analytics script loaded');
if (typeof gtag === 'function') {
console.log('gtag function available');
} else {
console.error('gtag function NOT available');
}
WooCommerce Tracking Installation
Enhanced Ecommerce Not Working
Common setup errors:
Missing WooCommerce integration:
- Most GA plugins require separate enhanced ecommerce activation
- Verify plugin supports GA4 ecommerce (not just Universal Analytics)
dataLayer not populated:
// Check dataLayer in console on product pages
console.log(window.dataLayer);
// Should show ecommerce objects
- Events not matching GA4 requirements:
- GA4 requires specific event names (view_item, add_to_cart, purchase)
- Parameters must follow GA4 schema
Verification steps:
- Visit product page → Check for
view_itemevent - Add to cart → Check for
add_to_cartevent - Complete purchase → Check for
purchaseevent with transaction data
// Monitor all dataLayer pushes
const originalPush = dataLayer.push;
dataLayer.push = function() {
console.log('dataLayer push:', arguments);
return originalPush.apply(dataLayer, arguments);
};
Configuration Issues
| Issue | Symptoms | Common Causes | Solutions |
|---|---|---|---|
| Admin Tracking | Own visits inflating data | User role exclusion not configured | Configure plugin to exclude logged-in admins; use analytics exclusion plugin |
| Duplicate Events | 2x event volume | Multiple tracking implementations | Audit all plugins and manual code; remove duplicates |
| Missing Pageviews | Low pageview count | SPA-like theme without virtual pageviews | Implement history change tracking; use GTM with history trigger |
| Cookie Consent Blocking | No tracking until consent | Scripts blocked before consent | Implement consent mode; use proper GTM consent template |
| Cross-Domain Tracking | Sessions breaking across domains | Linker parameters not configured | Set up GA4 cross-domain tracking; add domains to referral exclusion |
| Enhanced Ecommerce | No product data | dataLayer not implemented | Install WooCommerce-specific plugin; verify dataLayer structure |
| User ID Tracking | No user identification | User ID not passed to analytics | Implement User ID tracking with logged-in user data |
| Cached Pages | Stale data/no updates | Aggressive caching | Exclude tracking scripts from cache; use AJAX for dynamic data |
| Localhost Tracking | Development data in production | No environment filtering | Filter localhost; use separate GA4 properties for dev/prod |
| Bot Traffic | Inflated metrics | Bot filtering not enabled | Enable bot filtering in GA4; use Cloudflare bot protection |
Debugging with Developer Tools
Chrome DevTools Workflow
1. Network Tab Inspection
Check tracking requests:
- Open DevTools (F12) → Network tab
- Filter:
collect(for GA4) oranalyticsorgtag - Reload page
- Look for requests to:
What to verify:
Request URL: https://www.google-analytics.com/g/collect?v=2&tid=G-XXXXXXXXXX
Status: 200 OK
Query parameters:
- v=2 (protocol version)
- tid=G-XXXXXXXXXX (measurement ID)
- en=page_view (event name)
- dl=https://yoursite.com/page (document location)
Common issues:
- Status 0 → Request blocked by ad blocker or CSP
- 404 Not Found → Incorrect URL or syntax error
- No requests → Script not loading or JavaScript error
2. Console Debugging
Check for JavaScript errors:
// Look for errors related to:
// - Uncaught ReferenceError: gtag is not defined
// - Uncaught TypeError: Cannot read property 'push' of undefined
Test tracking manually:
// Test if gtag is available
typeof gtag
// Should return: "function"
// Test if dataLayer exists
window.dataLayer
// Should return: array
// Fire test event
gtag('event', 'test_event', {
'event_category': 'debugging',
'event_label': 'manual_test'
});
// Check if event was pushed
dataLayer[dataLayer.length - 1]
3. Application Tab Analysis
Check cookies:
- DevTools → Application → Cookies
- Look for:
_ga(GA4 client ID)_ga_XXXXXXXXXX(GA4 property-specific)_fbp(Facebook Pixel)_gcl_au(Google Ads)
Missing cookies indicate:
- Consent not granted
- Cookies blocked by browser
- Tracking script not executing
Check Local Storage:
- Some consent tools store preferences here
- GTM may use for data persistence
Browser Extensions for Debugging
Google Tag Assistant Legacy
How to use:
- Install Chrome extension
- Navigate to your WordPress site
- Click extension icon → Enable
- Refresh page
- Review tags found
What it shows:
Google Analytics Debugger
Enables debug mode:
// Shows detailed logging in console
// Install extension and reload page
// Check console for:
// - "Running command: ga("create"...)"
// - Event tracking details
// - Error messages
Meta Pixel Helper
For Facebook tracking:
- Install extension
- Visit your site
- Click extension icon
- Review pixel events
Check for:
- PageView events
- Custom conversions
- Pixel ID matches your account
- No errors or warnings
dataLayer Inspector+
Deep dataLayer inspection:
- Real-time dataLayer monitoring
- Event history
- Variable values
- GTM debugging
WordPress-Specific Debugging Plugins
Query Monitor
Track PHP errors affecting tracking:
// Install Query Monitor plugin
// Activate and check for:
// - PHP errors in tracking code
// - Slow database queries affecting page load
// - Hook execution order issues
WP Debugging Plugin
Enable WordPress debug mode:
// Adds to wp-config.php automatically:
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);
define('SCRIPT_DEBUG', true);
Check debug.log for:
WordPress-Specific Tracking Challenges
Plugin Conflicts
Identifying Conflicting Plugins
Common conflict categories:
Security Plugins:
- Wordfence
- Sucuri Security
- iThemes Security
Issues caused:
- Blocking external script loading
- Stripping JavaScript from headers
- Firewall blocking analytics requests
Solutions:
- Whitelist analytics domains
- Disable JavaScript filtering
- Add tracking domains to allowed list
Performance/Caching Plugins:
- WP Rocket
- W3 Total Cache
- Autoptimize
- LiteSpeed Cache
Issues caused:
- Minifying/combining breaks tracking code
- Caching pages with old tracking code
- Delaying JavaScript execution
Solutions:
WP Rocket: - File Optimization → Exclude gtag/analytics from minification - Add: gtag/js, analytics.js, gtm.js to exclusions W3 Total Cache: - Minify → Never minify following files: gtag, analytics, fbevents Autoptimize: - Exclude scripts from Autoptimize: gtag, analytics, fbevents.jsCookie Consent Plugins:
- CookieYes
- Complianz
- GDPR Cookie Consent
Issues caused:
- Blocking scripts before consent
- Not unblocking after consent granted
- Breaking script execution order
Solutions:
- Enable analytics in consent categories
- Use consent mode (GA4)
- Test consent flow thoroughly
Systematic Conflict Testing
Step-by-step isolation:
Backup your site
Create testing checklist:
☐ Deactivate all plugins except analytics plugin
☐ Test tracking (should work)
☐ Reactivate plugins one by one
☐ Test after each activation
☐ Note which plugin breaks tracking
- Test with default theme:
☐ Switch to Twenty Twenty-Four theme
☐ Test tracking
☐ If works, issue is theme-related
☐ If doesn't work, issue is plugin-related
- Use Health Check plugin:
- Enables troubleshooting mode
- Only affects your admin session
- Visitors see normal site
Theme Compatibility Issues
Page Builders
Elementor:
- Custom widgets may not trigger events
- Preview mode may block tracking
- Ajax page loads need virtual pageview tracking
Solution:
// Add to tracking code for Elementor
jQuery(document).on('elementor/frontend/init', function() {
elementorFrontend.hooks.addAction('frontend/element_ready/widget', function($scope) {
// Track widget interactions
$scope.find('a').on('click', function() {
gtag('event', 'click', {
'event_category': 'elementor_widget',
'event_label': $(this).text()
});
});
});
});
Divi Builder:
- Split testing features may cause duplicate tracking
- Visual Builder mode blocks some scripts
Gutenberg Blocks:
- Custom blocks need event handlers
- Dynamic blocks may load after tracking init
Solution for custom blocks:
// In custom block JavaScript
wp.domReady(() => {
const blocks = document.querySelectorAll('.wp-block-custom');
blocks.forEach(block => {
block.addEventListener('click', () => {
if (typeof gtag === 'function') {
gtag('event', 'block_interaction', {
'block_type': block.dataset.blockType
});
}
});
});
});
AJAX-Heavy Themes
Single Page Application (SPA) themes:
Problem: Only first pageview tracked, navigation doesn't trigger new pageviews
Solution - History Change Tracking:
// Add to theme or tracking code
(function() {
let lastPath = location.pathname;
// Monitor history changes
setInterval(function() {
if (location.pathname !== lastPath) {
lastPath = location.pathname;
// Send virtual pageview
if (typeof gtag === 'function') {
gtag('config', 'G-XXXXXXXXXX', {
'page_path': location.pathname + location.search
});
}
}
}, 500);
})();
Better solution with GTM:
- Create History Change trigger
- Add GA4 Configuration tag
- Set to fire on history change
Multisite Network Issues
WordPress Multisite challenges:
- Different tracking codes per site:
// functions.php in network-activated plugin
function multisite_analytics() {
$blog_id = get_current_blog_id();
$tracking_ids = array(
1 => 'G-AAAAAAAAAA', // Main site
2 => 'G-BBBBBBBBBB', // Site 2
3 => 'G-CCCCCCCCCC', // Site 3
);
$tracking_id = isset($tracking_ids[$blog_id]) ? $tracking_ids[$blog_id] : '';
if ($tracking_id) {
?>
<script async src="https://www.googletagmanager.com/gtag/js?id=<?php echo $tracking_id; ?>"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', '<?php echo $tracking_id; ?>');
</script>
<?php
}
}
add_action('wp_head', 'multisite_analytics', 1);
Cross-domain tracking between subsites:
- Configure cross-domain tracking
- Add all subdomains to GA4 settings
- Use same tracking ID or roll-up property
User role exclusions across network:
// Exclude super admins from all sites
function should_track_user() {
if (is_user_logged_in() && current_user_can('manage_network')) {
return false;
}
return true;
}
function conditional_analytics() {
if (should_track_user()) {
// Add tracking code
}
}
add_action('wp_head', 'conditional_analytics');
Membership and Restricted Content
MemberPress, Restrict Content Pro, etc.:
Challenge: Track member behavior without exposing user data
Solution - User ID Tracking:
function member_tracking() {
if (is_user_logged_in()) {
$user_id = get_current_user_id();
$user = wp_get_current_user();
?>
<script>
gtag('config', 'G-XXXXXXXXXX', {
'user_id': '<?php echo $user_id; ?>',
'dimension1': '<?php echo esc_js($user->roles[0]); ?>', // User role
'dimension2': '<?php echo esc_js(get_user_meta($user_id, 'membership_level', true)); ?>' // Membership level
});
</script>
<?php
}
}
add_action('wp_head', 'member_tracking', 20);
Error Messages and Solutions
Common Error Messages
"gtag is not defined"
Error in console:
Uncaught ReferenceError: gtag is not defined
Causes:
- Analytics script blocked by ad blocker
- Script loading after gtag() calls
- CSP blocking external scripts
- Network error loading script
Solutions:
Check script loading order:
<!-- This must come BEFORE any gtag() calls -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
gtag('config', 'G-XXXXXXXXXX');
</script>
Add fallback:
// Wait for gtag to be available
function safeGtag() {
if (typeof gtag === 'function') {
gtag.apply(this, arguments);
} else {
console.warn('gtag not available');
}
}
// Use safeGtag instead of gtag
safeGtag('event', 'click', {...});
"dataLayer is not defined"
Error:
Uncaught ReferenceError: dataLayer is not defined
Cause: GTM container not loaded before dataLayer.push()
Solution:
<!-- Initialize dataLayer BEFORE GTM -->
<script>
window.dataLayer = window.dataLayer || [];
</script>
<!-- Google Tag Manager -->
<script>(function(w,d,s,l,i){...GTM code...})(window,document,'script','dataLayer','GTM-XXXXXX');</script>
"Failed to load resource: net::ERR_BLOCKED_BY_CLIENT"
Error in Network tab:
www.google-analytics.com/g/collect - Failed to load resource: net::ERR_BLOCKED_BY_CLIENT
Cause: Ad blocker or browser extension blocking request
Solutions:
- Test in incognito mode without extensions
- Cannot fix for users with ad blockers
- Consider server-side tracking for critical metrics
- Use Google Tag Manager server-side container
"Refused to load script...Content Security Policy"
Error:
Refused to load the script 'https://www.googletagmanager.com/gtag/js' because it violates the following Content Security Policy directive: "script-src 'self'"
Solution: Update CSP headers:
// Add to functions.php or security plugin settings
add_filter('wp_headers', 'add_analytics_csp');
function add_analytics_csp($headers) {
$headers['Content-Security-Policy'] = "script-src 'self' 'unsafe-inline' https://www.googletagmanager.com https://www.google-analytics.com; connect-src 'self' https://www.google-analytics.com;";
return $headers;
}
WooCommerce-Specific Errors
Purchase events not firing
Debug checkout page:
// Add to thank you page temporarily
jQuery(document).ready(function($) {
console.log('Order data:', <?php echo json_encode($order->get_data()); ?>);
console.log('dataLayer:', window.dataLayer);
// Check if purchase event exists
const purchaseEvent = window.dataLayer.find(item => item.event === 'purchase');
if (purchaseEvent) {
console.log('Purchase event found:', purchaseEvent);
} else {
console.error('Purchase event NOT found in dataLayer');
}
});
Common causes:
- Cache serving old thank you page
- Payment gateway redirecting before event fires
- Order status not "completed"
- dataLayer not properly initialized
Performance Problems Affecting Tracking
Slow Page Load Breaking Tracking
Issue: Tracking scripts timeout or don't load
Solutions:
- Async loading:
<!-- Always use async for gtag -->
<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXXXX"></script>
- Defer non-critical scripts:
// Defer analytics scripts
function defer_analytics_scripts($tag, $handle, $src) {
$defer_scripts = array('google-analytics', 'gtag', 'facebook-pixel');
foreach ($defer_scripts as $script) {
if (strpos($handle, $script) !== false) {
return str_replace(' src', ' defer src', $tag);
}
}
return $tag;
}
add_filter('script_loader_tag', 'defer_analytics_scripts', 10, 3);
- Load GTM in head, not footer:
- GTM should be as high as possible in
<head> - Ensures tracking even if page load interrupted
- GTM should be as high as possible in
Mobile Performance Issues
Mobile-specific problems:
- Slow 3G/4G connections
- Limited processing power
- Aggressive browser power saving
Solutions:
Test mobile performance:
# Use Lighthouse mobile test
npx lighthouse https://yoursite.com --preset=perf --view --chrome-flags="--emulated-form-factor=mobile"
Optimize for mobile:
// Reduce tracking on slow connections
if ('connection' in navigator) {
const connection = navigator.connection;
if (connection.effectiveType === 'slow-2g' || connection.effectiveType === '2g') {
// Minimal tracking on slow connections
gtag('config', 'G-XXXXXXXXXX', {
'send_page_view': true,
'custom_map': {} // Disable custom dimensions
});
}
}
When to Contact Support
Analytics Platform Support
Contact GA4 Support when:
- Data appears in DebugView but not in reports (24+ hours)
- Events showing in real-time but not in standard reports
- Configuration issues in GA4 interface
- Data retention or privacy questions
What to provide:
- Measurement ID (G-XXXXXXXXXX)
- Specific page URLs
- Screenshots of DebugView
- Expected vs actual behavior
Plugin Support
Contact plugin developer when:
- Plugin settings save but don't apply
- Plugin conflicts with WordPress core functionality
- Error messages specifically mentioning the plugin
- Features documented but not working
What to provide:
- WordPress version
- Plugin version
- Other active plugins
- Theme name and version
- Error messages from debug log
- Steps to reproduce
Theme Support
Contact theme developer when:
- Tracking works with default theme but not with their theme
- Theme documentation mentions analytics integration that doesn't work
- Theme updates break previously working tracking
When to Hire a Developer
Complex scenarios requiring expert help:
- Custom ecommerce implementations beyond WooCommerce
- Advanced event tracking requiring JavaScript development
- Server-side tracking setup (GTM server-side)
- Data layer architecture for complex sites
- Custom WordPress plugin development for tracking
- GDPR-compliant tracking with complex requirements
- Multi-site network tracking with custom requirements
- Headless WordPress with separate frontend
Advanced Troubleshooting Techniques
Server-Side Debugging
Check server logs for tracking requests:
# Apache access log
tail -f /var/log/apache2/access.log | grep "gtag\|analytics"
# Nginx access log
tail -f /var/log/nginx/access.log | grep "gtag\|analytics"
Test with curl:
# Check if analytics script loads from server
curl -I https://www.google-analytics.com/analytics.js
# Should return 200 OK
Database-Level Debugging
Check plugin settings in database:
-- View all options related to analytics plugins
SELECT * FROM wp_options WHERE option_name LIKE '%analytics%';
SELECT * FROM wp_options WHERE option_name LIKE '%gtm%';
SELECT * FROM wp_options WHERE option_name LIKE '%google%';
Reset plugin settings if corrupted:
-- Backup first!
-- Delete specific plugin options
DELETE FROM wp_options WHERE option_name = 'monster_insights_settings';
Tracking Testing Workflow
Complete testing procedure:
Pre-deployment testing:
- Test on staging site
- Verify events in GA4 DebugView
- Check dataLayer in console
- Test consent flow
- Test on mobile devices
Deployment verification:
- Clear all caches
- Test in incognito window
- Verify events in real-time reporting
- Check for JavaScript errors
- Test from different locations
Post-deployment monitoring:
- Monitor real-time reports (24 hours)
- Compare to previous data
- Check conversion events
- Review bounce rate and engagement
Ongoing maintenance:
- Monthly tracking audit
- Review after plugin updates
- Test after theme changes
- Verify after WordPress core updates
General Fixes
For universal tracking concepts, see the Global Tracking Issues Hub.