signalpilot-sdk
v1.0.0
Published
Production-grade Customer Data Platform (CDP) SDK for browser-based event tracking with batching, retries, and reliable delivery. CDN-ready with UMD and ESM support.
Maintainers
Readme
SignalPilot JavaScript SDK
A production-grade Customer Data Platform (CDP) SDK for browser-based event tracking, similar to Segment or RudderStack. Features include event batching, user identification, anonymous tracking, reliable data delivery, and comprehensive error handling.
🚀 Features
- Event Batching: Automatic batching with configurable size and time limits
- User Identification: Track both anonymous and identified users
- Reliable Delivery: Retry logic with exponential backoff
- Page Unload Protection: Uses
sendBeaconto ensure no events are lost - Production Ready: Comprehensive error handling, logging, and monitoring capabilities
- ES6 Modules: Modern JavaScript with tree-shaking support
- Robust Error Handling: Structured error codes, custom error reporting, and monitoring
- CDN Ready: Available via CDN for easy integration without build tools
📦 Installation
NPM Package
npm install signalpilot-sdkCDN (Recommended for quick integration)
jsDelivr (Recommended):
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/signalpilot.umd.js"></script>UNPKG:
<script src="https://unpkg.com/[email protected]/dist/signalpilot.umd.js"></script>ES Modules (Modern browsers):
<script type="module">
import { init, track, identify, flush, getQueueStatus } from 'https://cdn.jsdelivr.net/npm/[email protected]/dist/signalpilot.esm.js';
</script>🎯 Quick Start
CDN Usage (Vanilla JavaScript)
<!DOCTYPE html>
<html>
<head>
<title>SignalPilot SDK Demo</title>
</head>
<body>
<h1>SignalPilot SDK Test</h1>
<!-- Load SignalPilot SDK from CDN -->
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/signalpilot.umd.js"></script>
<script>
// Initialize the SDK
SignalPilot.init({
projectKey: 'your-project-key',
batching: { enabled: true, maxBatchSize: 10, flushInterval: 5000 }
});
// Track an event
SignalPilot.track('page_viewed', {
page: 'homepage',
referrer: document.referrer
});
// Identify a user
SignalPilot.identify('user-123', {
name: 'John Doe',
email: '[email protected]'
});
</script>
</body>
</html>NPM Package Usage
import { init, track, identify, flush, getQueueStatus } from 'signalpilot-sdk';
// Initialize the SDK with error handling
init({
projectKey: 'your_project_key_here',
errorHandling: {
enabled: true,
customReporter: (error) => {
// Send to your error monitoring service (e.g., Sentry)
console.log('SDK Error:', error.code, error.message);
}
}
});
// Track events
track('page_viewed', { page: '/home', referrer: document.referrer });
track('button_clicked', { button_id: 'signup', location: 'header' });
// Identify users
identify('user_123', {
name: 'John Doe',
email: '[email protected]',
plan: 'premium'
});
// Force flush pending events (optional)
flush();
// Check queue status (useful for debugging)
console.log(getQueueStatus());🎯 Framework Integration
React
import React, { useEffect } from 'react';
// Load SignalPilot from CDN
const script = document.createElement('script');
script.src = 'https://cdn.jsdelivr.net/npm/[email protected]/dist/signalpilot.umd.js';
script.async = true;
document.head.appendChild(script);
function App() {
useEffect(() => {
script.onload = () => {
// Initialize SignalPilot
window.SignalPilot.init({
projectKey: 'your-project-key'
});
};
}, []);
const handleClick = () => {
window.SignalPilot.track('button_clicked', {
button: 'cta',
page: 'homepage'
});
};
return (
<div>
<button onClick={handleClick}>Track Event</button>
</div>
);
}Vue.js
<template>
<div>
<button @click="trackEvent">Track Event</button>
</div>
</template>
<script>
export default {
name: 'App',
mounted() {
// Load and initialize SignalPilot
this.loadSignalPilot();
},
methods: {
loadSignalPilot() {
const script = document.createElement('script');
script.src = 'https://cdn.jsdelivr.net/npm/[email protected]/dist/signalpilot.umd.js';
script.onload = () => {
window.SignalPilot.init({
projectKey: 'your-project-key'
});
};
document.head.appendChild(script);
},
trackEvent() {
window.SignalPilot.track('vue_button_clicked', {
component: 'App',
action: 'button_click'
});
}
}
}
</script>Next.js
// pages/_app.js
import { useEffect } from 'react';
function MyApp({ Component, pageProps }) {
useEffect(() => {
// Load SignalPilot only on client side
if (typeof window !== 'undefined') {
const script = document.createElement('script');
script.src = 'https://cdn.jsdelivr.net/npm/[email protected]/dist/signalpilot.umd.js';
script.onload = () => {
window.SignalPilot.init({
projectKey: 'your-project-key'
});
};
document.head.appendChild(script);
}
}, []);
return <Component {...pageProps} />;
}
export default MyApp;📊 Bundle Information
- UMD Bundle:
signalpilot.umd.js(~12KB, ~4.5KB gzipped) - ESM Bundle:
signalpilot.esm.js(~12KB, ~4.4KB gzipped) - Tree-shaking: Supported in ESM builds
- Browser Support: IE11+, Chrome, Firefox, Safari, Edge
🔒 Security
Integrity Checks
Always use integrity hashes when possible:
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/signalpilot.umd.js"
integrity="sha384-fJJ+wJD3IIQGcNjGQeRPnarWmeNGG0t5myR6V/wthqYVQFRM8dRxdq2YAtDbLScO"
crossorigin="anonymous"></script>🧪 Testing CDN Build
Test the CDN distribution locally:
npm run test:cdnThen open http://localhost:8000/dist/test-cdn.html in your browser.
📚 CDN Documentation
For comprehensive CDN usage documentation, see CDN.md.
⚙️ Error Handling Configuration
The SDK includes comprehensive error handling with structured error codes and custom reporting:
init({
projectKey: 'your_project_key',
errorHandling: {
enabled: true, // Enable error handling
logToConsole: true, // Log errors to console
customReporter: (error) => { // Custom error reporter
// Send to Sentry, LogRocket, etc.
Sentry.captureException(error);
},
errorSampling: 1.0, // Report 100% of errors
maxErrorsPerMinute: 100, // Rate limiting
deduplicationWindow: 60000 // Deduplicate errors (1 minute)
}
});Error Codes
The SDK uses structured error codes for easy debugging:
- E001: Missing project key
- E010: SDK not initialized
- E011: Invalid event name
- E012: Queue overflow
- E020: Network timeout
- E021: Network error
- E030: LocalStorage quota exceeded
- E040: Missing user ID
- E050: Batch too large
- E060: SendBeacon failed
Custom Error Reporting
// Example: Send errors to Sentry
init({
projectKey: 'your_project_key',
errorHandling: {
customReporter: (error) => {
Sentry.captureException(error, {
tags: {
sdk: 'signalpilot',
errorCode: error.code
},
extra: {
sdkVersion: error.sdkVersion,
context: error.context
}
});
}
}
});
// Example: Send errors to your analytics
init({
projectKey: 'your_project_key',
errorHandling: {
customReporter: (error) => {
analytics.track('sdk_error', {
error_code: error.code,
error_message: error.message,
sdk_version: error.sdkVersion
});
}
}
});⚙️ Batching Configuration
The SDK automatically batches events for optimal performance:
- Max Batch Size: 10 events (configurable)
- Flush Interval: 5 seconds (configurable)
- Auto-retry: Failed batches are retried with exponential backoff
- Page Unload: All pending events are sent using
sendBeacon
Batching Behavior
- Immediate Flush: When queue reaches 10 events
- Time-based Flush: Every 5 seconds (whichever comes first)
- Manual Flush: Call
flush()to force send all pending events - Page Unload: Automatic flush using
sendBeaconfor reliability
📊 API Reference
init(config)
Initialize the SDK with your project configuration.
init({
projectKey: 'your_project_key_here',
errorHandling: {
enabled: true,
customReporter: (error) => console.log('SDK Error:', error)
}
});Parameters:
config.projectKey(required): Your SignalPilot project keyconfig.errorHandling(optional): Error handling configuration
track(eventName, properties)
Track an event with optional properties.
track('purchase_completed', {
amount: 99.99,
currency: 'USD',
product_id: 'prod_123',
category: 'electronics'
});Parameters:
eventName(required): Name of the eventproperties(optional): Object containing event properties
identify(userId, traits)
Identify a user with their traits/attributes.
identify('user_123', {
name: 'John Doe',
email: '[email protected]',
plan: 'premium',
signup_date: '2024-01-15'
});Parameters:
userId(required): Unique identifier for the usertraits
