Matomo Troubleshooting & Debugging | Blue Frog Docs

Matomo Troubleshooting & Debugging

Troubleshooting playbook and diagnostics checklist for Matomo.

Overview

This guide helps you diagnose and resolve common Matomo (formerly Piwik) tracking issues. Matomo provides privacy-focused analytics with full data ownership, making proper configuration essential.

Debug Mode

Enable JavaScript Tracker Debugging

Enable debug mode to see detailed tracking information:

// Enable debug mode
_paq.push(['enableDebug']);

// Or configure Matomo object directly
var _paq = window._paq = window._paq || [];
_paq.push(['enableDebug']);
_paq.push(['trackPageView']);

Check Matomo Loading

Verify Matomo is loaded correctly:

// Check if Matomo tracker exists
if (typeof _paq !== 'undefined') {
  console.log('Matomo tracker loaded');
  console.log('_paq queue:', _paq);
} else {
  console.error('Matomo tracker not loaded');
}

// Check Matomo object
if (typeof Matomo !== 'undefined') {
  console.log('Matomo object loaded');
  console.log('Trackers:', Matomo.getAsyncTrackers());
} else {
  console.log('Matomo object not yet loaded (may load async)');
}

Common Issues

No Data in Reports

Symptoms: Tracking code installed but no data appears in Matomo.

Solutions:

  1. Verify tracking code installation:
<!-- Matomo tracking code should be before </head> or </body> -->
<script>
  var _paq = window._paq = window._paq || [];
  _paq.push(['trackPageView']);
  _paq.push(['enableLinkTracking']);
  (function() {
    var u="//matomo.example.com/";
    _paq.push(['setTrackerUrl', u+'matomo.php']);
    _paq.push(['setSiteId', '1']);
    var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
    g.async=true; g.src=u+'matomo.js'; s.parentNode.insertBefore(g,s);
  })();
</script>
  1. Check Site ID:
// Verify Site ID is correct
_paq.push(['setSiteId', '1']);  // Should match your Matomo site ID

// Log current tracker configuration
_paq.push([function() {
  var tracker = this;
  console.log('Tracker URL:', tracker.getTrackerUrl());
  console.log('Site ID:', tracker.getSiteId());
}]);
  1. Verify Matomo server URL:
// Check tracker URL points to your Matomo installation
_paq.push(['setTrackerUrl', 'https://matomo.example.com/matomo.php']);

// Test if matomo.php is accessible
// Visit: https://matomo.example.com/matomo.php
// Should return: GIF89a (1x1 tracking pixel)
  1. Check network requests:

    • Open DevTools → Network tab
    • Filter by "matomo"
    • Look for requests to matomo.php
    • Status should be 200 or 204
    • Response should be 1x1 GIF or empty
  2. Verify archiving is working:

    • For self-hosted Matomo, ensure cron job is running
    • Check System → General Settings → Archive Reports
    • Configure auto-archiving if not already set

Events Not Tracking

Symptoms: Custom events aren't appearing in Matomo.

Solutions:

  1. Verify event tracking syntax:
// Track event
_paq.push(['trackEvent', 'Category', 'Action', 'Name', Value]);

// Examples:
_paq.push(['trackEvent', 'Videos', 'Play', 'Product Demo']);
_paq.push(['trackEvent', 'Downloads', 'PDF', 'Whitepaper', 1]);
_paq.push(['trackEvent', 'Engagement', 'Button Click', 'Signup']);
  1. Check event appears in reports:

    • Go to Behavior → Events
    • May take a few minutes to appear
    • Check correct date range
  2. Enable debug mode to verify:

_paq.push(['enableDebug']);
_paq.push(['trackEvent', 'Test', 'Click', 'Debug Test']);
// Check browser console for tracking details
  1. Verify _paq is loaded before tracking:
// Wait for _paq to be ready
function trackMatomoEvent(category, action, name, value) {
  if (typeof _paq !== 'undefined') {
    _paq.push(['trackEvent', category, action, name, value]);
  } else {
    console.error('Matomo not loaded - event not tracked');
  }
}

trackMatomoEvent('Button', 'Click', 'CTA');

Goals Not Recording

Symptoms: Goal conversions not showing in reports.

Solutions:

  1. Verify goal is defined:

    • Go to Administration → Websites → Manage Goals
    • Check goal is active
    • Verify goal conditions are correct
  2. Track manual goal conversion:

// Trigger goal conversion manually
_paq.push(['trackGoal', 1]);  // Goal ID 1

// With revenue
_paq.push(['trackGoal', 1, 99.99]);

// Verify in console with debug mode
_paq.push(['enableDebug']);
_paq.push(['trackGoal', 1]);
  1. Check goal matching:

    • For URL-based goals, verify pattern matches
    • Test URL patterns in goal configuration
    • Check case sensitivity
  2. Verify timing:

    • Goals appear within minutes
    • Check correct date range in reports

Ecommerce Tracking Not Working

Symptoms: Ecommerce data not appearing.

Solutions:

  1. Enable ecommerce in Matomo:

    • Go to Administration → Websites → Manage
    • Enable "Ecommerce" for the website
  2. Track ecommerce order:

// Add product to cart
_paq.push(['addEcommerceItem',
  'SKU123',           // Product SKU
  'Product Name',     // Product name
  'Category',         // Product category
  99.99,              // Price
  1                   // Quantity
]);

// Track ecommerce order
_paq.push(['trackEcommerceOrder',
  'ORDER-123',        // Order ID (required, unique)
  109.99,             // Grand Total
  99.99,              // Sub total
  8.00,               // Tax
  5.00,               // Shipping
  false               // Discount
]);
  1. Track cart update:
// Track abandoned cart
_paq.push(['addEcommerceItem', 'SKU123', 'Product', 'Category', 99.99, 1]);
_paq.push(['trackEcommerceCartUpdate', 99.99]);
  1. Verify in reports:
    • Go to Ecommerce → Overview
    • Check Orders, Revenue tabs
    • May take a few minutes to appear

User ID Not Working

Symptoms: User ID not being set or tracked.

Solutions:

  1. Set User ID:
// Set User ID before trackPageView
_paq.push(['setUserId', 'user@example.com']);
_paq.push(['trackPageView']);

// Verify it's set
_paq.push([function() {
  console.log('User ID:', this.getUserId());
}]);
  1. Reset User ID:
// Reset User ID (e.g., on logout)
_paq.push(['resetUserId']);
_paq.push(['trackPageView']);
  1. Enable User ID reporting:
    • Go to Administration → Privacy → Users opt-out
    • Configure User ID settings

Cross-Domain Tracking Issues

Symptoms: Sessions breaking across domains.

Solutions:

  1. Configure cross-domain linking:
// Enable cross-domain linking
_paq.push(['enableCrossDomainLinking']);

// Set domains to track
_paq.push(['setDomains', ['*.example.com', '*.example.org']]);
  1. Verify link decoration:
// Links to other domains should have pk_vid parameter
// Example: https://example.org/page?pk_vid=...

// Test cross-domain tracking
_paq.push(['enableDebug']);
// Click link to other domain
// Check URL has pk_vid parameter
  1. Whitelist domains:
// Specify which domains to include
_paq.push(['setDomains', [
  '*.example.com',
  'subdomain.example.org',
  'checkout.example.net'
]]);

Debugging Techniques

Comprehensive Health Check

// Complete Matomo diagnostic
function matomoHealthCheck() {
  console.group('Matomo Health Check');

  // 1. Check if _paq exists
  if (typeof _paq === 'undefined') {
    console.error('❌ _paq not defined');
    console.groupEnd();
    return;
  }
  console.log('✓ _paq loaded');

  // 2. Get tracker info
  _paq.push([function() {
    var tracker = this;
    console.log('Tracker URL:', tracker.getTrackerUrl());
    console.log('Site ID:', tracker.getSiteId());
    console.log('User ID:', tracker.getUserId() || 'Not set');
    console.log('Visitor ID:', tracker.getVisitorId());
  }]);

  // 3. Send test page view
  _paq.push(['trackPageView', 'Health Check Test']);
  console.log('✓ Test page view sent');

  console.groupEnd();
}

matomoHealthCheck();

Monitor Tracking Requests

// Log all tracking requests
function monitorMatomoRequests() {
  const observer = new PerformanceObserver((list) => {
    list.getEntries().forEach((entry) => {
      if (entry.name.includes('matomo.php')) {
        console.log('Matomo tracking request:', entry.name);
        console.log('Duration:', entry.duration, 'ms');
      }
    });
  });

  observer.observe({ entryTypes: ['resource'] });
}

monitorMatomoRequests();

Test Custom Dimensions

// Set and verify custom dimensions
_paq.push(['setCustomDimension', 1, 'Value 1']);
_paq.push(['setCustomDimension', 2, 'Value 2']);

// Log custom dimensions
_paq.push([function() {
  var customDimensions = this.getCustomDimension(1);
  console.log('Custom Dimension 1:', customDimensions);
}]);

_paq.push(['trackPageView']);

Browser-Specific Issues

Safari ITP (Intelligent Tracking Prevention)

// Matomo uses first-party cookies, less affected by ITP
// But consider server-side tracking for better persistence

// Set cookie domain explicitly
_paq.push(['setCookieDomain', '*.example.com']);
_paq.push(['setDomains', ['*.example.com']]);

Content Security Policy (CSP)

<!-- Add Matomo domains to CSP -->
<meta http-equiv="Content-Security-Policy"
      content="script-src 'self' https://matomo.example.com 'unsafe-inline';
               img-src 'self' https://matomo.example.com;
               connect-src 'self' https://matomo.example.com;">

Do Not Track (DNT)

// Check if DNT is respected
_paq.push([function() {
  console.log('Respecting DNT:', this.isUserOptedOut());
}]);

// Disable DNT support if needed
_paq.push(['setDoNotTrack', false]);

Self-Hosted Matomo Issues

Archiving Not Running

Symptoms: Reports not updating, old data.

Solutions:

  1. Check cron job:
# Verify cron job is configured
crontab -l | grep matomo

# Should have something like:
# */5 * * * * /usr/bin/php /path/to/matomo/console core:archive --url=https://matomo.example.com
  1. Run manual archiving:
# SSH to server and run
cd /path/to/matomo
php console core:archive --url=https://matomo.example.com
  1. Configure auto-archiving:
    • Go to System → General Settings
    • Under "Archive Reports" set to "Yes"
    • Configure cron to run every 5-15 minutes

Database Performance Issues

// Check if tracking is slow
_paq.push([function() {
  var start = Date.now();
  this.trackPageView();
  var duration = Date.now() - start;
  console.log('Tracking took:', duration, 'ms');

  if (duration > 1000) {
    console.warn('Slow Matomo tracking - check database');
  }
}]);

Memory Limit Errors

# Increase PHP memory limit in php.ini
memory_limit = 256M

# Or in .htaccess
php_value memory_limit 256M

Data Quality Issues

Bot Filtering

// Matomo has built-in bot filtering
// Configure in Settings → Websites → Manage
// Check "Exclude visits based on user agent"

// Additional bot detection
_paq.push([function() {
  if (/bot|crawler|spider/i.test(navigator.userAgent)) {
    console.log('Bot detected - may not track');
  }
}]);

Duplicate Tracking

// Prevent duplicate page views
var pageTracked = false;

function trackPageOnce() {
  if (!pageTracked) {
    _paq.push(['trackPageView']);
    pageTracked = true;
  }
}

trackPageOnce();

GDPR Compliance

// Require consent before tracking
_paq.push(['requireConsent']);

// After user gives consent
_paq.push(['setConsentGiven']);

// Or require cookie consent
_paq.push(['requireCookieConsent']);
_paq.push(['setCookieConsentGiven']);

// Check consent status
_paq.push([function() {
  console.log('Has consent:', this.hasConsent());
}]);

Getting Help

Check Matomo System Check

For self-hosted Matomo:

  1. Go to Administration → System Check
  2. Review all system requirements
  3. Fix any warnings or errors

Diagnostic Report

// Generate comprehensive diagnostic
function matomoDiagnostics() {
  console.group('Matomo Diagnostics');

  if (typeof _paq === 'undefined') {
    console.error('_paq not loaded');
    console.groupEnd();
    return;
  }

  _paq.push([function() {
    var tracker = this;

    console.log('Configuration:');
    console.log('- Tracker URL:', tracker.getTrackerUrl());
    console.log('- Site ID:', tracker.getSiteId());
    console.log('- Cookie Domain:', tracker.getCookieDomain());

    console.log('\nUser:');
    console.log('- User ID:', tracker.getUserId() || 'Not set');
    console.log('- Visitor ID:', tracker.getVisitorId());

    console.log('\nSettings:');
    console.log('- Link Tracking:', tracker.isLinkTrackingEnabled());
    console.log('- Cookie Enabled:', tracker.isCookieEnabled());
    console.log('- Has Cookies:', tracker.hasCookies());
  }]);

  console.groupEnd();
}

matomoDiagnostics();

Contact Support

  1. Matomo Forums:

  2. Matomo Documentation:

  3. Professional Support:

    • For self-hosted: Matomo On-Premise Support
    • For cloud: Matomo Cloud Support
    • Email: support@matomo.org (paid plans)

Best Practices

Regular Testing

// Create test suite
function runMatomoTests() {
  console.group('Matomo Tests');

  // 1. Test page view
  _paq.push(['trackPageView', 'Test Page']);
  console.log('✓ Page view tracked');

  // 2. Test event
  _paq.push(['trackEvent', 'Test', 'Click', 'Test Event']);
  console.log('✓ Event tracked');

  // 3. Test custom dimension
  _paq.push(['setCustomDimension', 1, 'Test Value']);
  console.log('✓ Custom dimension set');

  // 4. Test user ID
  _paq.push(['setUserId', 'test_user']);
  console.log('✓ User ID set');

  console.groupEnd();
}

runMatomoTests();

Monitor in Production

// Log Matomo errors
window.addEventListener('error', function(e) {
  if (e.message && (e.message.includes('matomo') || e.message.includes('piwik'))) {
    console.error('Matomo error:', e);
    // Send to error tracking service
  }
});

// Monitor Matomo availability
setInterval(function() {
  if (typeof _paq === 'undefined') {
    console.error('Matomo tracker unavailable');
    // Alert monitoring service
  }
}, 60000); // Check every minute

Testing Checklist

  • Matomo script loaded successfully
  • Site ID is correct
  • Tracker URL is correct and accessible
  • Page views tracking
  • Events tracking correctly
  • Goals recording (if configured)
  • Ecommerce tracking (if enabled)
  • User ID being set (if applicable)
  • Custom dimensions working (if used)
  • No console errors
  • Network requests successful
  • Data appearing in reports
// SYS.FOOTER