npm installnpm run buildThis creates three bundles in dist/:
index.js(CommonJS)index.esm.js(ES Module)index.umd.js(Browser UMD)
Open examples/basic.html in your browser to see a live demo with all features.
npm install @stickyqr/analyticsimport { Analytics } from '@stickyqr/analytics';
const analytics = new Analytics({
writeKey: 'your-write-key'
});
// Track events
analytics.track('Button Clicked', { buttonId: 'signup' });
// Identify users
analytics.identify('user-123', {
email: 'user@example.com',
name: 'John Doe'
});<script src="https://cdn.stickyqr.com/analytics/1.2.0/index.umd.js"></script>
<script>
const analytics = new StickyQRAnalytics.Analytics({
writeKey: 'your-write-key'
});
analytics.track('Page Viewed');
</script>Copy dist/index.umd.js to your project:
<script src="/js/stickyqr-analytics-sdk.js"></script>
<script>
const analytics = new StickyQRAnalytics.Analytics({
writeKey: 'your-write-key'
});
</script>const analytics = new StickyQRAnalytics.Analytics({
writeKey: 'your-write-key',
debug: true // Enable console logging
});// Simple event
analytics.track('Button Clicked');
// Event with properties
analytics.track('Product Viewed', {
productId: 'prod-123',
price: 99.99
});// Identify user
analytics.identify('user-123', {
email: 'user@example.com',
name: 'John Doe',
plan: 'premium'
});
// Update traits for current user
analytics.identify(undefined, {
lastLogin: new Date()
});// Auto-tracked by default
// Or manually track
analytics.page('Home');
analytics.page('Pricing', 'Marketing', { plan: 'enterprise' });analytics.reset();analytics.reset() rotates anonymousId and clears the current user state, but keeps the persisted deviceId.
Your backend needs to implement one endpoint to receive events:
POST /v1/batch
// Express.js example
app.post('/v1/batch', async (req, res) => {
const { batch } = req.body;
// Process events (save to database, queue, etc.)
for (const event of batch) {
await processEvent(event);
}
res.json({ success: true });
});See API_SPEC.md for complete backend implementation.
import { Analytics } from '@stickyqr/analytics';
import { createContext, useContext } from 'react';
const AnalyticsContext = createContext<Analytics | null>(null);
export function AnalyticsProvider({ children, writeKey }) {
const analytics = new Analytics({ writeKey });
return (
<AnalyticsContext.Provider value={analytics}>
{children}
</AnalyticsContext.Provider>
);
}
export function useAnalytics() {
return useContext(AnalyticsContext);
}
// Usage
function MyComponent() {
const analytics = useAnalytics();
return (
<button onClick={() => analytics.track('Button Clicked')}>
Click me
</button>
);
}// Product view
analytics.track('Product Viewed', {
productId: 'prod-123',
name: 'Product Name',
price: 99.99,
category: 'Electronics'
});
// Add to cart
analytics.track('Product Added', {
productId: 'prod-123',
price: 99.99,
quantity: 1
});
// Purchase
analytics.track('Order Completed', {
orderId: 'order-123',
revenue: 99.99,
currency: 'USD',
products: [
{ productId: 'prod-123', quantity: 1, price: 99.99 }
]
});// 1. User signs up
analytics.track('Signup Started', {
method: 'email'
});
// 2. User completes signup
analytics.identify('user-123', {
email: 'user@example.com',
name: 'John Doe',
signupDate: new Date()
});
analytics.track('Signup Completed', {
method: 'email'
});
// 3. Link anonymous ID to user ID
analytics.alias('user-123', analytics.user().anonymousId);import { Analytics, ConsoleLoggerPlugin } from '@stickyqr/analytics';
const analytics = new Analytics({
writeKey: 'your-write-key',
plugins: [new ConsoleLoggerPlugin()]
});import { GoogleAnalyticsPlugin } from '@stickyqr/analytics';
const analytics = new Analytics({
writeKey: 'your-write-key',
plugins: [
new GoogleAnalyticsPlugin({
measurementId: 'G-XXXXXXXXXX'
})
]
});import { DeviceEnrichmentPlugin } from '@stickyqr/analytics';
const analytics = new Analytics({
writeKey: 'your-write-key',
plugins: [new DeviceEnrichmentPlugin()]
});
// All events now include device, browser, OS infoFull configuration options:
const analytics = new Analytics({
// Required
writeKey: 'your-write-key',
// API endpoint
// Queue settings
flushAt: 20, // Flush after 20 events
flushInterval: 10000, // Flush every 10 seconds
maxQueueSize: 100, // Max 100 events in queue
retryAttempts: 3, // Retry 3 times
// Features
debug: false, // Debug mode
trackPageViews: true, // Auto-track page views
// Storage
anonymousIdKey: 'stickyqr_analytics_anonymous_id',
deviceIdKey: 'stickyqr_analytics_device_id',
userIdKey: 'stickyqr_analytics_user_id',
// Plugins
plugins: []
});// Enable debug mode
const analytics = new Analytics({
writeKey: 'your-write-key',
debug: true
});
// View current user
console.log(analytics.user()); // includes userId, anonymousId, deviceId, and traits
// View analytics state
analytics.debug();
// Check queue size
console.log(analytics.queue.size());
// Manually flush queue
await analytics.flush();- Customize: Update package name, branding in
package.json - Backend: Implement
/v1/batchendpoint (seeAPI_SPEC.md) - Plugins: Create custom plugins (see
PLUGIN_GUIDE.md) - Deploy: Publish to NPM or host on CDN
- Monitor: Track usage and errors
README.md- Complete documentationPLUGIN_GUIDE.md- Plugin developmentAPI_SPEC.md- Backend API specificationPROJECT_STRUCTURE.md- Project overviewexamples/- Code examples
- Check browser console for errors
- Enable debug mode:
debug: true - Check network tab for API requests
- Verify
writeKeyandapiHost
- Check localStorage availability
- Check cookie permissions
- Falls back to in-memory storage
# Clean install
rm -rf node_modules package-lock.json
npm install
# Rebuild
npm run build