Simple Analytics Tracking Approaches | OpsBlu Docs

Simple Analytics Tracking Approaches

Compare server-side and client-side tracking approaches in Simple Analytics — performance, accuracy, and implementation trade-offs.

Overview

Simple Analytics offers flexible tracking approaches tailored to different use cases and technical requirements. Understanding the differences between client-side JavaScript tracking and server-side API tracking helps you choose the best implementation for your specific needs while maintaining Simple Analytics' privacy-first philosophy.

Both tracking methods provide the same privacy guarantees - no cookies, no user tracking, full GDPR compliance - but offer different trade-offs in terms of implementation complexity, ad-blocker resistance, and data accuracy.

Client-Side Tracking

Client-side tracking uses JavaScript that runs in visitors' browsers to automatically collect and send pageview data to Simple Analytics.

Basic Implementation

The standard Simple Analytics script:

<script async defer src="https://scripts.simpleanalyticscdn.com/latest.js"></script>
<noscript><img src="https://queue.simpleanalyticscdn.com/noscript.gif" alt="" referrerpolicy="no-referrer-when-downgrade" /></noscript>

Custom Hostname

For proxy implementations or custom domains:

<script async defer src="https://scripts.simpleanalyticscdn.com/latest.js" data-hostname="example.com"></script>

Automatic Features

Client-side tracking automatically provides:

  • Pageview Tracking: Every page load is recorded
  • Referrer Detection: Where visitors came from
  • Screen Resolution: Device viewport data
  • Language Detection: Browser language preferences
  • Path Tracking: Which pages are visited

Client-Side Advantages

  1. Simple Setup: Just add one script tag
  2. Automatic Tracking: No manual pageview calls needed
  3. Rich Context: Access to full browser environment
  4. SPA Support: Built-in support for hash-based routing
  5. No Server Load: Processing happens in the browser
  6. Noscript Fallback: Image pixel for non-JavaScript users

Client-Side Limitations

  1. Ad Blocker Susceptibility: Can be blocked by privacy extensions
  2. JavaScript Dependency: Requires JavaScript enabled
  3. Client Performance: Minor page load overhead
  4. Browser Restrictions: Subject to browser security policies

Server-Side Tracking

Server-side tracking sends analytics data directly from your application server to Simple Analytics API, bypassing the browser entirely.

API Endpoint

POST https://queue.simpleanalyticscdn.com/post

Basic Implementation

Send pageview from backend:

curl -X POST https://queue.simpleanalyticscdn.com/post \
  -H "Content-Type: application/json" \
  -H "User-Agent: Mozilla/5.0..." \
  -d '{
    "type": "pageview",
    "hostname": "example.com",
    "path": "/page",
    "referrer": "https://google.com"
  }'

Node.js Implementation

const fetch = require('node-fetch');

async function trackPageview(req) {
  try {
    await fetch('https://queue.simpleanalyticscdn.com/post', {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
        'User-Agent': req.headers['user-agent'] || 'Unknown'
      },
      body: JSON.stringify({
        type: 'pageview',
        hostname: 'example.com',
        path: req.path,
        referrer: req.headers.referer || '',
        ua: req.headers['user-agent']
      })
    });
  } catch (error) {
    console.error('Simple Analytics error:', error);
  }
}

// Express middleware
app.use((req, res, next) => {
  trackPageview(req);
  next();
});

Python/Flask Implementation

import requests

def track_pageview(request):
    try:
        requests.post(
            'https://queue.simpleanalyticscdn.com/post',
            json={
                'type': 'pageview',
                'hostname': 'example.com',
                'path': request.path,
                'referrer': request.headers.get('Referer', ''),
                'ua': request.headers.get('User-Agent', '')
            },
            headers={
                'Content-Type': 'application/json',
                'User-Agent': request.headers.get('User-Agent', 'Unknown')
            }
        )
    except Exception as e:
        print(f"Simple Analytics error: {e}")

# Flask before_request
@app.before_request
def before_request():
    track_pageview(request)

PHP Implementation

<?php
function trackPageview() {
    $data = [
        'type' => 'pageview',
        'hostname' => 'example.com',
        'path' => $_SERVER['REQUEST_URI'],
        'referrer' => $_SERVER['HTTP_REFERER'] ?? '',
        'ua' => $_SERVER['HTTP_USER_AGENT'] ?? ''
    ];

    $ch = curl_init('https://queue.simpleanalyticscdn.com/post');
    curl_setopt($ch, CURLOPT_POST, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
    curl_setopt($ch, CURLOPT_HTTPHEADER, [
        'Content-Type: application/json',
        'User-Agent: ' . ($_SERVER['HTTP_USER_AGENT'] ?? 'Unknown')
    ]);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

    curl_exec($ch);
    curl_close($ch);
}

trackPageview();
?>

Ruby/Rails Implementation

require 'net/http'
require 'json'

def track_pageview(request)
  uri = URI('https://queue.simpleanalyticscdn.com/post')

  http = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl = true

  req = Net::HTTP::Post.new(uri.path, {
    'Content-Type' => 'application/json',
    'User-Agent' => request.user_agent || 'Unknown'
  })

  req.body = {
    type: 'pageview',
    hostname: 'example.com',
    path: request.path,
    referrer: request.referer || '',
    ua: request.user_agent || ''
  }.to_json

  http.request(req)
rescue => e
  Rails.logger.error "Simple Analytics error: #{e}"
end

# Rails before_action
before_action :track_analytics

def track_analytics
  track_pageview(request)
end

Server-Side Advantages

  1. Ad Blocker Immunity: Cannot be blocked by browser extensions
  2. Guaranteed Tracking: Works regardless of client settings
  3. API Endpoints: Track server-only actions (downloads, API calls)
  4. Full Control: Complete control over what data is sent
  5. Privacy Enhanced: No client-side scripts or fingerprinting
  6. Backend Context: Access to server-side session data

Server-Side Limitations

  1. Manual Implementation: Requires backend code changes
  2. Server Resources: Adds load to application server
  3. No Automatic Features: Must manually track each pageview
  4. Limited Context: No access to browser-specific data
  5. Complexity: More complex than script tag

Hybrid Approach

Combine both methods for comprehensive coverage:

<!-- Client-side for automatic pageview tracking -->
<script async defer src="https://scripts.simpleanalyticscdn.com/latest.js"></script>
// Server-side for critical actions
app.post('/api/subscribe', async (req, res) => {
  // Track server-side for reliability
  await trackEvent('subscription', {
    plan: req.body.plan
  });

  res.json({ success: true });
});

Choosing the Right Approach

Use Client-Side When:

  • Static Websites: Content sites, blogs, portfolios
  • Quick Setup: You need analytics running immediately
  • Standard Tracking: Pageviews and basic referrer data suffice
  • Limited Backend: No server-side code or static hosting
  • SPA Applications: Single-page apps with client-side routing

Example Use Cases:

  • Marketing websites
  • Documentation sites
  • Blogs and content platforms
  • Static site generators (Gatsby, Hugo, Jekyll)

Use Server-Side When:

  • Ad Blocker Concerns: Significant portion of users use ad blockers
  • API Services: Tracking server-only endpoints
  • Critical Conversions: Must track important events reliably
  • Downloads: Tracking file downloads or PDF views
  • Privacy Maximum: Want zero client-side tracking
  • Server-Rendered: Primarily server-side rendered application

Example Use Cases:

  • SaaS applications
  • API-first services
  • Download portals
  • Privacy-critical applications
  • B2B tools with tech-savvy users

Use Hybrid Approach When:

  • Maximum Coverage: Want comprehensive data collection
  • Both Contexts: Need both client and server data
  • Fallback Required: Critical tracking needs redundancy
  • Mixed Architecture: Combination of static and dynamic pages

Example Use Cases:

  • E-commerce platforms
  • Enterprise applications
  • Complex web applications
  • Sites with both public and authenticated sections

Implementation Examples

SPA Route Tracking (Client-Side)

For React Router:

import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';

function usePageViews() {
  let location = useLocation();

  useEffect(() => {
    if (window.sa_pageview) {
      window.sa_pageview();
    }
  }, [location]);
}

For Vue Router:

router.afterEach((to, from) => {
  if (window.sa_pageview) {
    window.sa_pageview();
  }
});

Download Tracking (Server-Side)

app.get('/download/:file', async (req, res) => {
  // Track download server-side
  await trackEvent('download', {
    file: req.params.file
  });

  // Serve file
  res.download(`./files/${req.params.file}`);
});

Form Submission (Hybrid)

// Client-side event
document.getElementById('contact-form').addEventListener('submit', function(e) {
  sa_event('form_submit_attempt');
});

// Server-side confirmation
app.post('/api/contact', async (req, res) => {
  // Track successful submission server-side
  await trackEvent('form_submit_success', {
    form_type: 'contact'
  });

  res.json({ success: true });
});

Validation and Testing

Test Client-Side Tracking

// 1. Check script loaded
console.log(typeof sa_pageview !== 'undefined' ? 'Loaded' : 'Not loaded');

// 2. Manually trigger pageview
if (window.sa_pageview) window.sa_pageview();

// 3. Check Network tab
// Look for requests to queue.simpleanalyticscdn.com

Test Server-Side Tracking

# Test with curl
curl -X POST https://queue.simpleanalyticscdn.com/post \
  -H "Content-Type: application/json" \
  -H "User-Agent: TestAgent/1.0" \
  -d '{
    "type": "pageview",
    "hostname": "example.com",
    "path": "/test"
  }' \
  -v

Dashboard Verification

  1. Wait 2-5 minutes for data processing
  2. Check Simple Analytics dashboard
  3. Verify pageviews appear
  4. Confirm correct paths and referrers

Troubleshooting

Issue Method Cause Solution
No pageviews appearing Client-side Script blocked or not loading Check browser console; verify script URL
Ad blocker blocking Client-side Browser extension active Switch to server-side or use proxy
400 Bad Request Server-side Invalid payload format Verify JSON structure matches API spec
Duplicate pageviews Hybrid Both methods tracking same action Implement deduplication logic
Missing user agent Server-side Header not passed Ensure UA header is included
CORS errors Client-side Security policy issue Simple Analytics handles CORS; check network
Server load high Server-side Too many sync requests Use async tracking or batching
Path not showing Both Path not sent correctly Verify path parameter in request

Best Practices

  1. Start Simple: Begin with client-side, add server-side only if needed
  2. Async Tracking: Don't block application flow for analytics
  3. Error Handling: Gracefully handle tracking failures
  4. Test Both Environments: Verify in dev and production
  5. Monitor Performance: Track impact on page load and server resources
  6. Respect Privacy: Don't send PII regardless of method
  7. Use Noscript: Include noscript fallback for client-side
  8. Document Choice: Record why you chose a particular method

Privacy Considerations

Both methods maintain Simple Analytics' privacy guarantees:

  • No cookies used
  • No personal data collected
  • No cross-session tracking
  • No fingerprinting
  • GDPR compliant by default

Server-Side Advantage: Even more private as no client-side scripts run at all.

Performance Comparison

Aspect Client-Side Server-Side
Page Load Impact Minimal (~2KB script) None
Server Load None Minimal per request
Setup Time < 5 minutes 30-60 minutes
Maintenance None Update with code changes
Ad Blocker Resistance Low High
Accuracy 80-95% ~100%