JavaScript Tracker
The frontend JavaScript tracker automatically detects and sends events to the REST API. It’s lightweight, privacy-respecting, and requires no jQuery dependency.
Overview
The tracker (assets/js/tracker.js) is automatically enqueued on all frontend pages (excluding admin). It:
- Respects Do Not Track settings
- Detects events based on DOM interactions
- Sends data via the REST API
- Handles errors gracefully
- Manages session tracking
File Structure
assets/js/tracker.js # Main tracker scriptIntegration
Automatic Loading
The tracker is automatically loaded via WordPress’s script enqueueing:
wp_enqueue_script(
'sarai-analytics-tracker',
plugin_url . 'assets/js/tracker.js',
array(),
'1.0.0',
true // Load in footer
);Localization
Configuration is passed via wp_localize_script():
SaraiAnalytics: {
endpoint: '/wp-json/sarai-analytics/v1/event',
events: ['random_click', 'image_mode', 'smi_click', 'search', 'page_view']
}Event Detection
Page View Events
Trigger: Page load (after DOM ready)
Code:
function trackPageView() {
if (hasEvent('page_view')) {
sendEvent('page_view', {});
}
}Conditions: Only fires if page_view is in allowed events list
Image Mode Events
Trigger: Page load with /images/ in URL path
Detection Pattern: window.location.pathname.indexOf('/images') !== -1
Code:
function trackImageMode() {
if (window.location.pathname.indexOf('/images') !== -1 && hasEvent('image_mode')) {
sendEvent('image_mode', { path: window.location.pathname });
}
}Supported Paths:
/images//category/artwork/images//tag/watercolor/images/
Random Click Events
Trigger: Click on elements with specific selectors
Selectors:
#random-icon-link.surprise-me
Code:
document.addEventListener('click', function (event) {
var target = event.target;
var randomLink = target.closest('#random-icon-link, .surprise-me');
if (randomLink && hasEvent('random_click')) {
sendEvent('random_click', { from: window.location.pathname });
}
});Event Data: Current page pathname
SMI Click Events
Trigger: Click on download/SMI related elements
Selectors:
.download-hires[data-sarai-smi]
Code:
document.addEventListener('click', function (event) {
var target = event.target;
var button = target.closest ? target.closest('.download-hires, [data-sarai-smi]') : null;
if (button && hasEvent('smi_click')) {
sendEvent('smi_click', { label: button.textContent || '' });
}
});Event Data: Button text content
Search Events
Trigger: Form submission with search input
Detection:
- Form submit event
- Input with
type="search"orname="s" - Must be inside a
<form>element
Code:
document.addEventListener('submit', function (event) {
var form = event.target;
if (form.tagName === 'FORM') {
var input = form.querySelector('input[type="search"], input[name="s"]');
if (input && hasEvent('search')) {
sendEvent('search', { query: input.value || '' });
}
}
});Event Data: Search query value
Privacy Features
Do Not Track Support
The tracker checks multiple Do Not Track indicators:
if (navigator.doNotTrack === '1' ||
window.doNotTrack === '1' ||
navigator.msDoNotTrack === '1') {
return; // Exit early
}Supported Headers:
navigator.doNotTrack(standard)window.doNotTrack(legacy)navigator.msDoNotTrack(Microsoft)
No Personal Data
- No IP addresses collected
- No user IDs stored
- No cookies read (except session cookie set by server)
- Only anonymous session tracking
Error Handling
Network Failures
fetch(endpoint, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify(payload)
}).catch(function () {
return null; // Silent failure
});Behavior:
- Failed requests are silently ignored
- No console errors thrown
- No impact on page performance
Missing Configuration
if (!window.SaraiAnalytics || !window.SaraiAnalytics.endpoint) {
return; // Exit if not configured
}Safety Checks:
- Verifies
SaraiAnalyticsobject exists - Ensures endpoint URL is available
- Checks for allowed events list
Event Sending
Payload Structure
{
event_type: 'page_view',
event_data: {},
page_url: window.location.href,
referrer: document.referrer || ''
}Request Details
- Method: POST
- Content-Type: application/json
- Body: JSON-encoded payload
- Endpoint:
/wp-json/sarai-analytics/v1/event
Session Management
Sessions are managed server-side, but the client sends the session cookie automatically with each request.
Customization
Adding Custom Events
To add custom event detection:
- Add event type to allowed events filter
- Extend the tracker script
- Add detection logic
Example:
// In PHP
add_filter( 'sarai_analytics_allowed_events', function( $events ) {
$events[] = 'custom_button_click';
return $events;
} );
// In JavaScript (custom script)
document.addEventListener('click', function(event) {
if (event.target.matches('.custom-button')) {
sendEvent('custom_button_click', { buttonId: event.target.id });
}
});Modifying Selectors
To change detection selectors, create a custom tracker:
// Custom tracker.js
(function() {
// Copy original tracker code
// Modify selectors as needed
var customSelectors = {
random: '#my-random-link, .my-surprise',
smi: '.my-download, [data-custom-smi]'
};
// Use customSelectors in event listeners
})();Conditional Loading
To load tracker only on specific pages:
add_action( 'wp_enqueue_scripts', function() {
if ( is_page( 'special-page' ) ) {
wp_enqueue_script( 'sarai-analytics-tracker' );
wp_localize_script( 'sarai-analytics-tracker', 'SaraiAnalytics', array(
'endpoint' => rest_url( 'sarai-analytics/v1/event' ),
'events' => apply_filters( 'sarai_analytics_allowed_events', array( 'page_view' ) )
) );
}
}, 20 ); // Priority after default enqueuePerformance
Bundle Size
- Minified: ~2KB
- Gzipped: ~1KB
- No external dependencies
Execution
- Loads in footer to avoid render blocking
- Uses passive event listeners where supported
- Minimal DOM queries
- Asynchronous event sending
Browser Support
- Modern browsers with
fetch()API - IE11+ with polyfill (if needed)
- Graceful degradation in older browsers
Debugging
Console Logging
Add debug logging to the tracker:
function sendEvent(eventType, eventData) {
console.log('Sarai Analytics Event:', eventType, eventData); // Debug line
var payload = {
event_type: eventType,
event_data: eventData || {},
page_url: window.location.href,
referrer: document.referrer || ''
};
fetch(endpoint, { /* ... */ });
}Verifying Events
- Open browser developer tools
- Go to Network tab
- Filter by
/wp-json/sarai-analytics/ - Trigger events and verify requests
Testing Do Not Track
- Enable Do Not Track in browser settings
- Check that no network requests are made
- Verify
navigator.doNotTrack === '1'
Troubleshooting
Events Not Firing
Common Issues:
- Do Not Track enabled: Check browser settings
- Event not in allowed list: Verify
SaraiAnalytics.eventsarray - Selector mismatch: Confirm CSS selectors match your HTML
- JavaScript errors: Check console for syntax errors
Network Errors
Symptoms: Events not reaching server
- CORS issues: Verify REST API is accessible
- Endpoint wrong: Check
SaraiAnalytics.endpointvalue - Rate limited: Server returns 429 status
- Invalid event type: Server returns 400 status
Performance Impact
Symptoms: Slow page loads
- Multiple trackers: Ensure only one instance loaded
- Heavy event listeners: Minimize DOM event bindings
- Large payloads: Keep event data minimal
Future Enhancements
Potential tracker improvements:
- Custom event API for programmatic tracking
- Intersection Observer for view events
- Service Worker support for offline events
- Batch sending for multiple events
- Custom data attributes for flexible targeting
This tracker provides reliable, lightweight event detection for the Sarai Analytics plugin.