@cruxstack/browser-sdk
v1.0.5
Published
A lightweight, privacy-focused JavaScript SDK for web analytics and event tracking. Built with TypeScript, featuring automatic event capture, event-time environment snapshots, intelligent queuing, and robust error handling.
Readme
Cruxstack Web SDK
A lightweight, privacy-focused JavaScript SDK for web analytics and event tracking. Built with TypeScript, featuring automatic event capture, event-time environment snapshots, intelligent queuing, and robust error handling.
🚀 Quick Start
Installation
npm install @cruxstack/browser-sdkBasic Setup
import { init, cruxCustom } from "@cruxstack/browser-sdk";
// Initialize the SDK
init({
clientId: "your-client-id",
customerId: "customer-123", // optional
customerName: "your-customer-name", // optional
// userId: 'user-123', // optional; omit to keep user anonymous
autoCapture: true, // optional, defaults to true
debugLog: false, // optional, defaults to false
});
// Track custom events
cruxCustom("purchase_completed", {
amount: 99.99,
product: "premium_plan",
currency: "USD",
});📖 API Reference
Configuration
interface CruxstackConfig {
clientId: string; // Required: Your client identifier
customerId?: string; // Optional: Customer identifier
customerName?: string; // Optional: Human-readable customer name
userId?: string; // Optional: User identifier; omit for anonymous
autoCapture?: boolean; // Optional: Enable/disable automatic capture (default: true)
debugLog?: boolean; // Optional: Enable debug logging (default: false)
}Core Functions
init(config: CruxstackConfig)
Initializes the SDK with your configuration.
init({
clientId: "my-client-123",
customerId: "customer-456",
userId: "user-456",
autoCapture: true,
debugLog: false,
});cruxCustom(eventName: string, properties?: object)
Tracks custom events with optional properties. Event IDs are automatically generated as UUIDs.
// Basic event
cruxCustom("button_clicked");
// Event with properties
cruxCustom("purchase_completed", {
amount: 99.99,
product: "premium_plan",
currency: "USD",
});
// Event with complex data
cruxCustom("user_action", {
action: "signup",
source: "homepage",
campaign: "summer-sale",
});getUserTraits(customerId: string, userIds: string[])
// Get traits for specific customer and users
const userTraits = await getUserTraits('customer-123', ['user-1', 'user-2']);
// Example response
{
"success": true,
"data": [
{
"userId": "test-user11",
"traits": [
{
"key": "power_user",
"value": {
"value": 0.5,
"confidence": 1,
"computed_at": 1756798053239
}
}
],
"lastUpdated": "2025-09-02T07:27:33.239Z"
}
],
"meta": {
"total": 1,
"requested": 1
}
}createUsers(payload)
Create or upsert users for a customer.
import { createUsers } from '@cruxstack/browser-sdk';
await createUsers({
customer_id: 'Wealthwise-v1',
users: [
{
user_id: 'test-userId-2',
job_title: 'SDE',
country: 'United Kingdom',
city: 'Manchester',
},
],
});Headers are sent automatically: x-client-id and x-customer-id.
getUsers({ customerId, page, limit })
Fetch users for a customer with pagination.
import { getUsers } from '@cruxstack/browser-sdk';
const res = await getUsers({
customerId: 'Wealthwise-v1',
page: 0,
limit: 10,
});
Utility Functions
getSessionInfo()
Returns current session information.
const sessionInfo = getSessionInfo();
console.log(sessionInfo);
// {
// sessionId: "abc-123-def",
// userId: "user-456",
// isInitialized: true
// }flushEvents()
Manually flush queued events to the server.
// Force send all queued events
await flushEvents();getQueueStatus()
Check the status of the event queue.
const queueStatus = getQueueStatus();
console.log(queueStatus);
// {
// length: 5,
// events: [...]
// }clearQueue()
Clear all queued events (use with caution).
clearQueue(); // Removes all pending eventsresetSession()
Reset the current session (useful for logout scenarios).
resetSession(); // Creates a new sessioncleanup()
Clean up the SDK and remove event listeners.
cleanup(); // Remove listeners and reset state🎯 Automatic Event Capture
The SDK automatically captures the following events:
Clicks
- Trigger: User clicks on actionable elements
- Data: Element info, position, timing, context
- Privacy: Sensitive elements (passwords, emails) are ignored
Form Interactions
- Events:
form_change,form_focus,form_blur,form_submit - Data: Form structure, field data, validation status
- Privacy: Input values are redacted for sensitive fields
Page Views
- Trigger: Page load, SPA route changes (pushState/replaceState/popstate/hashchange)
- Data (ev only): session metrics, timing, scroll depth percentage
- SPA Support: Automatic detection for SPA navigations
🔧 Advanced Usage
Custom Event Properties
cruxCustom("user_action", {
// User context
userId: "user-123",
userType: "premium",
// Business data
productId: "prod-456",
category: "electronics",
price: 299.99,
// Custom metadata
source: "homepage",
campaign: "summer-sale",
timestamp: Date.now(),
});Session Management
// Get current session info
const session = getSessionInfo();
// Reset session (useful for logout)
resetSession();
// Check if SDK is initialized
if (isInitialized()) {
// SDK is ready
}Debug Mode
init({
clientId: "your-client-id",
debugLog: true, // Enable debug logging
});
// Check queue status in console
console.log(getQueueStatus());API Data Fetching
// Fetch customer traits for personalization
async function loadUserProfile(customerId) {
try {
const traits = await getUserTraits(customerId);
console.log("Customer traits:", traits);
// Use traits for personalization
if (traits.traits.trait === "power_user") {
showPremiumFeatures();
}
} catch (error) {
console.error("Failed to load customer traits:", error);
}
}🛡️ Privacy & Security
Automatic Data Filtering
- Password fields are never tracked
- Email addresses are redacted
- Credit card data is filtered
- Sensitive form fields are ignored
GDPR Compliance
- Session-based tracking with automatic expiration
- No persistent user identification without explicit consent
- Easy data deletion via
clearQueue()andresetSession()
Custom Privacy Controls
// Add data attributes to ignore elements
<button data-cruxstack-ignore>Don't track this</button>
// Ignore sensitive forms
<form data-cruxstack-ignore>
<input type="password" />
</form>🔄 Offline Support
The SDK automatically handles offline scenarios:
- Events are queued in localStorage when offline or on network errors
- Flush on reconnect/init: queue flushes on
onlineand once oninit() - Persistent storage survives page refreshes (max 1000 events; oldest trimmed)
- Batch processing: flush sends events in batches of 10 and loops until the queue is empty
- Unload-safe delivery: on page unload, a best-effort
sendBeaconbatch is attempted (non-blocking)
🚨 Error Handling
Network Failures
- Network failures: Events are queued in localStorage.
- Flush failures: If a batch fails during flush, it is re-added once and the flush stops (no tight loop).
- 4xx: Typically treated as permanent by your backend; queued items will remain until next flush attempt.
Queue Management
- Maximum 1000 events in queue to prevent memory issues (oldest trimmed).
- Batches of 10 per flush iteration; continues until queue empties or a batch fails.
🌐 Browser Support
- Modern Browsers: Chrome 60+, Firefox 55+, Safari 12+, Edge 79+
- Mobile: iOS Safari 12+, Chrome Mobile 60+
- Features: ES2017+, localStorage, fetch API, Performance API
📦 Build Outputs
The SDK is built with Rollup and provides multiple output formats:
- CommonJS (
dist/index.js): For Node.js environments - ES Modules (
dist/index.mjs): For modern bundlers - UMD (
dist/index.min.js): For browser CDN usage (minified)
🔧 Development
TypeScript Support
import { init, cruxCustom, CruxstackConfig } from "@cruxstack/browser-sdk";
const config: CruxstackConfig = {
clientId: "my-client",
userId: "user-123",
};
init(config);
cruxCustom("test_event", { data: "value" });Debug Mode
init({
clientId: "your-client-id",
debugLog: true,
});
// Check browser console for detailed logs