@cruxstack/browser-sdk
Version:
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.
366 lines (270 loc) • 8.4 kB
Markdown
# 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
```bash
npm install @cruxstack/browser-sdk
```
### Basic Setup
```javascript
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
```typescript
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.
```javascript
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.
```javascript
// 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)`
```javascript
// Get traits for specific customer
const userTraits = await getUserTraits('customer-123');
// 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
}
}
```
<!-- Intentionally no generic callApiMethod exported by the SDK. -->
### Utility Functions
#### `getSessionInfo()`
Returns current session information.
```javascript
const sessionInfo = getSessionInfo();
console.log(sessionInfo);
// {
// sessionId: "abc-123-def",
// userId: "user-456",
// isInitialized: true
// }
```
#### `flushEvents()`
Manually flush queued events to the server.
```javascript
// Force send all queued events
await flushEvents();
```
#### `getQueueStatus()`
Check the status of the event queue.
```javascript
const queueStatus = getQueueStatus();
console.log(queueStatus);
// {
// length: 5,
// events: [...]
// }
```
#### `clearQueue()`
Clear all queued events (use with caution).
```javascript
clearQueue(); // Removes all pending events
```
#### `resetSession()`
Reset the current session (useful for logout scenarios).
```javascript
resetSession(); // Creates a new session
```
#### `cleanup()`
Clean up the SDK and remove event listeners.
```javascript
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
```javascript
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
```javascript
// 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
```javascript
init({
clientId: "your-client-id",
debugLog: true, // Enable debug logging
});
// Check queue status in console
console.log(getQueueStatus());
```
### API Data Fetching
```javascript
// 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()` and `resetSession()`
### Custom Privacy Controls
```javascript
// 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:
1. **Events are queued** in localStorage when offline or on network errors
2. **Flush on reconnect/init**: queue flushes on `online` and once on `init()`
3. **Persistent storage** survives page refreshes (max 1000 events; oldest trimmed)
4. **Batch processing**: flush sends events in batches of 10 and loops until the queue is empty
5. **Unload-safe delivery**: on page unload, a best-effort `sendBeacon` batch 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
```typescript
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
```javascript
init({
clientId: "your-client-id",
debugLog: true,
});
// Check browser console for detailed logs
```