Overview
Kissmetrics offers both client-side (JavaScript) and server-side tracking options, each with distinct advantages and use cases. Understanding when to use each approach is critical for building a comprehensive analytics implementation that captures all important user actions across your entire application stack.
Most robust implementations use a hybrid approach, combining client-side tracking for user interface interactions with server-side tracking for backend operations and sensitive transactions.
Client-Side Tracking
Client-side tracking uses JavaScript code that runs in the user's browser. The Kissmetrics JavaScript library (_kmq) captures events as they happen in the user's session.
Advantages
Automatic Context: Captures browser information, page URLs, referrers, and user agent data automatically.
Real-Time Interaction: Track clicks, form submissions, scrolling, and other UI interactions as they happen.
Easy Setup: Simple to implement with just a JavaScript snippet.
Session Continuity: Maintains user session and identity across page views.
Basic Implementation
// Record a simple event
_kmq.push(['record', 'Viewed Product']);
// Record an event with properties
_kmq.push(['record', 'Added to Cart', {
'Product Name': 'Blue Widget',
'Product ID': 'SKU-12345',
'Price': 29.99,
'Quantity': 2
}]);
// Identify a user
_kmq.push(['identify', 'user@example.com']);
// Set user properties
_kmq.push(['set', {
'Plan Type': 'Premium',
'Account Created': '2024-01-15',
'Total Purchases': 5
}]);
Common Client-Side Use Cases
Page Views and Navigation:
// Track specific page views
_kmq.push(['record', 'Viewed Pricing Page']);
// Track with context
_kmq.push(['record', 'Viewed Blog Post', {
'Post Title': document.title,
'Category': 'Marketing',
'Author': 'John Smith'
}]);
UI Interactions:
// Button clicks
document.getElementById('signup-btn').addEventListener('click', function() {
_kmq.push(['record', 'Clicked Signup Button', {
'Button Location': 'Header'
}]);
});
// Form submissions
_kmq.push(['trackSubmit', 'contact-form', 'Submitted Contact Form']);
User Engagement:
// Feature usage
_kmq.push(['record', 'Used Export Feature', {
'Export Format': 'CSV',
'Records Exported': 1250
}]);
// Video engagement
_kmq.push(['record', 'Watched Video', {
'Video Title': 'Product Demo',
'Duration Watched': 120,
'Completion Rate': 75
}]);
Client-Side Limitations
- Cannot track server-side processes or background jobs
- Events may not fire if user closes browser/tab quickly
- Can be blocked by ad blockers or privacy tools
- Exposes API key in source code
- Unsuitable for sensitive or PII data
Server-Side Tracking
Server-side tracking sends events from your backend servers directly to Kissmetrics. This approach gives you complete control over what data is sent and when.
Advantages
Reliability: Events are guaranteed to be tracked; not affected by browser issues or ad blockers.
Security: API keys and sensitive data stay on your server.
Backend Events: Track operations that happen on your server (payments, subscriptions, webhooks).
Data Control: Full control over data formatting and what information is sent.
No Client Required: Track users even when they're not actively browsing (scheduled jobs, email opens, etc.).
HTTP API Implementation
Kissmetrics provides a simple HTTP API for server-side tracking:
# Record an event
curl "https://trk.kissmetrics.io/e" \
-d "_k=YOUR_API_KEY" \
-d "_p=user@example.com" \
-d "_n=Subscription%20Renewed" \
-d "Plan=Pro" \
-d "Amount=99"
# Set user properties
curl "https://trk.kissmetrics.io/s" \
-d "_k=YOUR_API_KEY" \
-d "_p=user@example.com" \
-d "Plan%20Type=Enterprise" \
-d "MRR=499"
# Alias users (connect identities)
curl "https://trk.kissmetrics.io/a" \
-d "_k=YOUR_API_KEY" \
-d "_p=user@example.com" \
-d "_n=anonymous_user_123"
Server-Side Libraries
Node.js:
const KISSmetrics = require('kissmetrics');
const km = new KISSmetrics('YOUR_API_KEY');
// Record event
km.record('user@example.com', 'Completed Purchase', {
'Order ID': 'ORD-12345',
'Revenue': 149.99,
'Items': 3
});
// Set properties
km.set('user@example.com', {
'Lifetime Value': 599.99,
'Total Orders': 4,
'Last Purchase Date': new Date().toISOString()
});
Python:
from KISSmetrics import KM
km = KM('YOUR_API_KEY')
# Record event
km.record('user@example.com', {
'_n': 'Subscription Cancelled',
'Reason': 'Too Expensive',
'Plan': 'Pro',
'Months Subscribed': 6
})
# Set properties
km.set('user@example.com', {
'Account Status': 'Cancelled',
'Cancellation Date': '2024-03-15'
})
Ruby:
require 'kmts'
km = Kmts.new('YOUR_API_KEY')
# Record event
km.record('user@example.com', 'Upgraded Plan', {
'From Plan' => 'Basic',
'To Plan' => 'Pro',
'Price Difference' => 50
})
Common Server-Side Use Cases
Payment Processing:
// After successful payment
km.record(user.email, 'Payment Processed', {
'Amount': payment.amount,
'Currency': payment.currency,
'Payment Method': payment.method,
'Transaction ID': payment.id
});
Subscription Management:
// Subscription events
km.record(user.email, 'Subscription Created', {
'Plan': subscription.plan,
'Billing Cycle': subscription.cycle,
'Trial End Date': subscription.trialEnd
});
km.record(user.email, 'Subscription Renewed', {
'Plan': subscription.plan,
'Amount': subscription.amount,
'Next Billing Date': subscription.nextBilling
});
Webhook Events:
// Stripe webhook handler
app.post('/webhooks/stripe', async (req, res) => {
const event = req.body;
if (event.type === 'payment_intent.succeeded') {
km.record(event.data.object.customer.email, 'Payment Succeeded', {
'Amount': event.data.object.amount / 100,
'Currency': event.data.object.currency
});
}
});
Background Jobs:
// Daily report generation
cron.schedule('0 0 * * *', async () => {
const users = await getActiveUsers();
users.forEach(user => {
km.set(user.email, {
'Daily Active': true,
'Last Active Date': new Date().toISOString(),
'Session Count': user.sessionCount
});
});
});
Hybrid Approach (Recommended)
The most effective Kissmetrics implementation combines both client-side and server-side tracking to capture the complete user journey.
Implementation Strategy
Use Client-Side For:
- Page views and navigation
- Button clicks and UI interactions
- Form field interactions
- Client-side feature usage
- Real-time user engagement
Use Server-Side For:
- Payment processing and transactions
- Subscription lifecycle events
- API usage and integrations
- Webhook processing
- Background jobs and scheduled tasks
- Sensitive operations
Example: E-Commerce Checkout Flow
// Client-side: User starts checkout
_kmq.push(['record', 'Started Checkout', {
'Cart Value': cart.total,
'Items in Cart': cart.items.length
}]);
// Client-side: User enters shipping info
_kmq.push(['record', 'Completed Shipping Info']);
// Server-side: Payment is processed
km.record(user.email, 'Payment Processed', {
'Order ID': order.id,
'Amount': order.total,
'Payment Method': order.paymentMethod
});
// Server-side: Order is fulfilled
km.record(user.email, 'Order Shipped', {
'Order ID': order.id,
'Tracking Number': shipment.tracking
});
Choosing the Right Approach
Decision Matrix
| Scenario | Recommended Approach | Reason |
|---|---|---|
| User clicks button | Client-Side | Immediate UI feedback |
| User submits form | Client-Side | Capture form data |
| Payment processed | Server-Side | Security and reliability |
| Subscription renewed | Server-Side | Backend operation |
| Page view | Client-Side | Browser context needed |
| Webhook received | Server-Side | No client present |
| Feature toggle used | Client-Side | UI interaction |
| API call made | Server-Side | Backend operation |
| Email sent | Server-Side | No browser involved |
| User scrolls | Client-Side | Browser event |
Troubleshooting
Events Not Appearing from Server-Side
Issue: Server-side events aren't showing in Kissmetrics.
Solutions:
- Verify API key is correct
- Check that user identifier matches client-side identifier
- Ensure URL encoding for event names and properties
- Check server firewall isn't blocking outbound requests
- Verify HTTPS is being used
Duplicate Events
Issue: Same event tracked twice (once client, once server).
Solutions:
// Client-side: Track initiation only
_kmq.push(['record', 'Initiated Purchase']);
// Server-side: Track completion only
km.record(user.email, 'Completed Purchase', {
'Order ID': order.id
});
Identity Mismatch
Issue: Client-side and server-side events don't connect to same user.
Solutions:
- Ensure same identifier format (e.g., both use email)
- Call identify on client before server events
- Use alias to connect different identifiers:
// Server-side
km.alias(serverUserId, clientEmail);
Best Practices
- Identify Users Consistently: Use the same identifier (email or user ID) across both client and server
- Track Business-Critical Events Server-Side: Don't rely on client-side tracking for revenue or conversion events
- Keep Sensitive Data Server-Side: Never send PII or payment details via client-side tracking
- Use Descriptive Event Names: Make events self-explanatory (e.g., "Completed Purchase" not "CP")
- Include Relevant Properties: Add context to events with meaningful properties
- Test Both Approaches: Verify events appear correctly in Kissmetrics for both tracking methods
- Document Your Strategy: Maintain a tracking plan that specifies which events use which method