Overview
Pirsch offers flexible tracking options to suit different implementation needs and privacy requirements. You can choose between client-side JavaScript tracking, server-side API tracking, or a hybrid approach that combines both methods for maximum reliability and data accuracy.
Understanding the differences between these approaches helps you select the best tracking method for your application architecture, user privacy requirements, and data collection goals. Both methods maintain Pirsch's privacy-first philosophy while offering 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 the visitor's browser to collect and send analytics data to Pirsch. This is the simplest and most common implementation method.
Basic Implementation
Add the Pirsch script to your HTML pages:
<script defer src="https://api.pirsch.io/pirsch.js"
id="pirschjs"
data-code="YOUR_IDENTIFICATION_CODE"></script>
Extended Script (with Event Tracking)
For sites that need custom event tracking:
<script defer src="https://api.pirsch.io/pirsch-extended.js"
id="pirschextendedjs"
data-code="YOUR_IDENTIFICATION_CODE"></script>
Configuration Options
Customize client-side tracking behavior with data attributes:
<script defer src="https://api.pirsch.io/pirsch-extended.js"
id="pirschextendedjs"
data-code="YOUR_CODE"
data-disable-cookies="true"
data-dev="localhost,dev.example.com"></script>
Available Options:
data-code: Your website identification code (required)data-disable-cookies: Disable all cookies (default: false)data-dev: Comma-separated list of dev domains to ignoredata-disable-scripts: Disable automatic script trackingdata-disable-outbound-links: Disable automatic outbound link tracking
Client-Side Advantages
- Simple Setup: Just add a script tag to your HTML
- Automatic Pageview Tracking: No manual tracking code required
- Session Management: Browser handles session continuity
- Hash Route Support: Automatically tracks single-page application navigation
- Lower Server Load: Processing happens in the browser
- Rich Context: Access to full browser environment and DOM
Client-Side Limitations
- Ad Blocker Susceptibility: Some ad blockers may block Pirsch scripts
- JavaScript Required: Won't track users with JavaScript disabled
- Browser-Dependent: Relies on browser capabilities and settings
- Client Performance: Adds small overhead to page load
- CORS Considerations: Subject to browser security policies
Server-Side Tracking
Server-side tracking sends analytics data directly from your application server to Pirsch's API. This method bypasses the browser entirely, making it immune to client-side blocking.
Basic API Implementation
Send pageviews from your backend:
curl -X POST "https://api.pirsch.io/api/v1/hit" \
-H "Authorization: Bearer YOUR_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/page",
"ip": "192.168.1.1",
"user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64)...",
"accept_language": "en-US,en;q=0.9",
"referrer": "https://google.com"
}'
Node.js Implementation
const axios = require('axios');
async function trackPageview(req) {
try {
await axios.post('https://api.pirsch.io/api/v1/hit', {
url: `https://example.com${req.path}`,
ip: req.ip,
user_agent: req.headers['user-agent'],
accept_language: req.headers['accept-language'],
referrer: req.headers['referer'] || ''
}, {
headers: {
'Authorization': `Bearer ${process.env.PIRSCH_ACCESS_TOKEN}`,
'Content-Type': 'application/json'
}
});
} catch (error) {
console.error('Pirsch tracking error:', error);
}
}
// Use in Express middleware
app.use((req, res, next) => {
trackPageview(req);
next();
});
Python/Flask Implementation
import requests
import os
def track_pageview(request):
try:
requests.post(
'https://api.pirsch.io/api/v1/hit',
json={
'url': f"https://example.com{request.path}",
'ip': request.remote_addr,
'user_agent': request.headers.get('User-Agent', ''),
'accept_language': request.headers.get('Accept-Language', ''),
'referrer': request.headers.get('Referer', '')
},
headers={
'Authorization': f"Bearer {os.environ['PIRSCH_ACCESS_TOKEN']}",
'Content-Type': 'application/json'
}
)
except Exception as e:
print(f"Pirsch tracking error: {e}")
# Use in Flask
@app.before_request
def before_request():
track_pageview(request)
PHP Implementation
<?php
function trackPageview() {
$data = [
'url' => 'https://example.com' . $_SERVER['REQUEST_URI'],
'ip' => $_SERVER['REMOTE_ADDR'],
'user_agent' => $_SERVER['HTTP_USER_AGENT'] ?? '',
'accept_language' => $_SERVER['HTTP_ACCEPT_LANGUAGE'] ?? '',
'referrer' => $_SERVER['HTTP_REFERER'] ?? ''
];
$ch = curl_init('https://api.pirsch.io/api/v1/hit');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, [
'Authorization: Bearer ' . getenv('PIRSCH_ACCESS_TOKEN'),
'Content-Type: application/json'
]);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_exec($ch);
curl_close($ch);
}
trackPageview();
?>
Server-Side Advantages
- Ad Blocker Immunity: Cannot be blocked by browser extensions
- Complete Data Control: Full control over what data is sent
- No JavaScript Dependency: Works regardless of browser settings
- Privacy Enhancement: More control over IP anonymization
- Server Context: Access to server-side session data
- Reliable Tracking: Not affected by client-side errors
Server-Side Limitations
- Implementation Complexity: Requires backend code changes
- Server Resources: Adds load to your application server
- Manual Pageview Tracking: Must explicitly track each pageview
- No Automatic Events: Cannot track client-side interactions directly
- Session Management: Must handle session continuity manually
Hybrid Approach
Combine both methods for maximum reliability and comprehensive tracking.
Implementation Strategy
<!-- Client-side script for automatic tracking -->
<script defer src="https://api.pirsch.io/pirsch-extended.js"
id="pirschextendedjs"
data-code="YOUR_CODE"></script>
// Server-side tracking as fallback
// Only track critical conversions server-side
app.post('/api/purchase', async (req, res) => {
// Track purchase server-side for reliability
await trackEvent({
event_name: 'purchase',
event_meta: {
value: req.body.amount,
product: req.body.product_id
}
});
res.json({ success: true });
});
Deduplication Strategy
Prevent double-counting by setting session identifiers:
// Client-side sets session ID
pirsch('pageview', {
meta: {
session_id: generateSessionId()
}
});
// Server-side uses same session ID
trackPageview({
session_id: req.session.id
});
Choosing the Right Approach
Use Client-Side When:
- You want simple, quick implementation
- Your site is primarily content-driven
- You don't need to track users with ad blockers
- You want automatic SPA route tracking
- Server resources are limited
Use Server-Side When:
- Ad blocker immunity is critical
- You need to track API endpoints or downloads
- You have sensitive conversion data
- You need full control over tracked data
- Your application is primarily server-rendered
Use Hybrid Approach When:
- You need maximum data accuracy
- Critical conversions must be tracked reliably
- You want comprehensive event coverage
- You have both client and server interactions
- Budget allows for additional implementation complexity
Validation and Testing
Test Client-Side Tracking
- Open your website in a browser
- Open Developer Tools (F12)
- Go to Network tab
- Filter by "pirsch.io"
- Navigate pages and verify requests are sent
- Check Console for any JavaScript errors
// Test script load in console
console.log(typeof pirsch !== 'undefined' ? 'Pirsch loaded' : 'Pirsch not loaded');
Test Server-Side Tracking
Monitor your application logs:
# Check if API calls are successful
# Look for 200 OK responses from api.pirsch.io
tail -f /var/log/application.log | grep pirsch
Test with curl:
curl -X POST "https://api.pirsch.io/api/v1/hit" \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"url": "https://example.com/test",
"ip": "127.0.0.1",
"user_agent": "Test Agent"
}' \
-v
Verify in Dashboard
- Wait 5-10 minutes for data processing
- Check Pirsch dashboard for new pageviews
- Verify data appears correctly
- Check that referrer and page information is accurate
Troubleshooting
| Issue | Tracking Method | Cause | Solution |
|---|---|---|---|
| No data appearing | Client-side | Script blocked or not loading | Check browser console for errors; verify script URL |
| 401 Unauthorized | Server-side | Invalid or expired access token | Regenerate token in Pirsch dashboard settings |
| 403 Forbidden | Server-side | Wrong API endpoint or permissions | Verify endpoint URL and token permissions |
| Duplicate pageviews | Hybrid | Both client and server tracking same action | Implement session-based deduplication |
| Missing user agent | Server-side | Not passing browser headers | Ensure user_agent field includes full header value |
| Ad blocker blocking | Client-side | Browser extension blocking script | Switch to server-side or use proxy |
| CORS errors | Client-side | Browser security policy | Pirsch handles CORS; check for network issues |
| High server load | Server-side | Too many tracking requests | Implement request batching or async processing |
Best Practices
- Start Simple: Begin with client-side tracking, add server-side only if needed
- Monitor Performance: Track the impact of analytics on page load and server resources
- Secure Tokens: Keep server-side access tokens in environment variables
- Error Handling: Implement graceful error handling for tracking failures
- Test Both Environments: Verify tracking works in development and production
- Document Your Choice: Record why you chose a particular tracking method
- Regular Audits: Periodically verify tracking accuracy and performance