<?php // matomo-heartbeat-handler.php class MatomoHeartbeatHandler private $matomoUrl; private $siteId; private $tokenAuth; public function __construct($matomoUrl, $siteId, $tokenAuth = null) $this->matomoUrl = rtrim($matomoUrl, '/'); $this->siteId = $siteId; $this->tokenAuth = $tokenAuth;
bindEvents() // Track user activity events const activityEvents = ['mousedown', 'mousemove', 'keydown', 'scroll', 'touchstart', 'click']; activityEvents.forEach(event => document.addEventListener(event, () => this.resetIdleTimer()); ); // Page visibility API document.addEventListener('visibilitychange', () => if (document.hidden) this.stopHeartbeat(); this.log('Page hidden, stopping heartbeat'); else this.startHeartbeat(); this.log('Page visible, starting heartbeat'); ); // Before page unload window.addEventListener('beforeunload', () => this.sendFinalHeartbeat(); ); matomo heartbeat
header('Content-Type: application/json'); echo json_encode($result); <!DOCTYPE html> <html> <head> <!-- Matomo Tracking Code --> <script> var _paq = window._paq = window._paq || []; _paq.push(['trackPageView']); _paq.push(['enableLinkTracking']); (function() var u="https://your-matomo-domain.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> JavaScript Heartbeat Tracker // matomo-heartbeat
sendHeartbeat(type) const now = Date.now(); const timeSinceLastHeartbeat = (now - this.lastHeartbeatTime) / 1000; // Don't send heartbeat if too short if (timeSinceLastHeartbeat < this.options.minVisitLength && type === 'ongoing') return; const heartbeatData = action_name: 'Heartbeat', e_c: 'Engagement', e_a: type, e_n: 'User Activity', e_v: Math.floor(timeSinceLastHeartbeat), _cvar: JSON.stringify( heartbeat_interval: this.options.heartbeatInterval, time_on_page: Math.floor((now - this.visitStartTime) / 1000), total_engaged_time: this.totalEngagedTime + Math.floor((now - this.lastHeartbeatTime) / 1000) ) ; // Send to Matomo if (window._paq) window._paq.push(['trackEvent', heartbeatData.e_c, heartbeatData.e_a, heartbeatData.e_n, heartbeatData.e_v]); // Optional: track custom variable window._paq.push(['setCustomVariable', 1, 'HeartbeatType', type, 'page']); this.log(`Heartbeat sent: $type`, heartbeatData); this.lastHeartbeatTime = now; // seconds minVisitLength: 5
I'll help you develop a Matomo Heartbeat feature. This feature tracks user engagement time more accurately by sending periodic heartbeats to Matomo analytics. 1. JavaScript Heartbeat Tracker // matomo-heartbeat.js class MatomoHeartbeat { constructor(options = {}) this.options = heartbeatInterval: 15, // seconds minVisitLength: 5, // minimum seconds for a valid visit idleTimeout: 30, // seconds of inactivity to stop heartbeat debug: false, ...options ; this.intervalId = null; this.idleCheckId = null; this.lastActivity = Date.now(); this.visitStartTime = null; this.totalEngagedTime = 0; this.isActive = false; this.lastHeartbeatTime = null; this.init();