@trust1io/tracker
v0.0.2
Published
Tracking SDK for browser and Node.js
Readme
@trust1io/tracker
Client SDK for the Trustshop Tracking API. Supports both browser and Node.js environments. Queues events locally, flushes them in batches, and handles page-unload delivery via sendBeacon (browser). Includes automatic browser fingerprinting and device detection in the browser.
Installation
Script Tag
<script src="https://asset.trustshop.io/sdk/tracker.js"></script>Exposes TrustshopTracker and TrustshopError as globals.
ES Module (Browser)
pnpm add @trust1io/trackerimport { TrustshopTracker, TrustshopError } from "@trust1io/tracker";Node.js
pnpm add @trust1io/trackerimport { NodeTracker, TrustshopError } from "@trust1io/tracker/node";Requires Node.js 18+.
Quick Start (Browser)
const tracker = new TrustshopTracker({
endpoint: "https://tracking.trustshop.io",
apiKey: "trk_your_api_key",
});
// Track events
tracker.track("page_view", { page: "/home", referrer: document.referrer });
tracker.track("purchase", { product_id: "prod_123", amount: 49.99 });
// Track element visibility (fires when 50% visible for 500ms)
const unsub = tracker.trackVisible("#hero-banner", "banner_impression");
// Track clicks
tracker.trackClick(".buy-button", "buy_click", { product: "widget" });
// Cleanup on teardown
tracker.destroy();Quick Start (Node.js)
import { NodeTracker } from "@trust1io/tracker/node";
const tracker = new NodeTracker({
endpoint: "https://tracking.trustshop.io",
apiKey: "trk_your_api_key",
});
// Track server-side events
tracker.track("order_completed", { orderId: "ord_123", total: 99.99 });
// Parse device info from incoming request UA
tracker.track(
"api_call",
{ path: "/checkout" },
{ deviceType: "web", browserName: "Chrome" },
);
// Graceful shutdown
await tracker.flush();
tracker.destroy();Graceful Shutdown
The Node.js timer is unref()-ed so it won't keep your process alive. To ensure all queued events are delivered before exit:
process.on("beforeExit", async () => {
await tracker.flush();
tracker.destroy();
});Configuration
Browser (TrustshopTracker)
new TrustshopTracker({
// Required
endpoint: string, // API base URL (no trailing slash)
apiKey: string, // Bearer token (trk_...)
// Optional
shopId?: string, // Default shop ID for all events
flushInterval?: number, // Auto-flush interval in ms (default: 5000)
flushSize?: number, // Queue threshold for immediate flush (default: 20)
maxQueueSize?: number, // Max queue before dropping oldest (default: 1000)
autoFingerprint?: boolean, // Auto browser fingerprint (default: true)
autoDevice?: boolean, // Auto browser/OS detection (default: true)
onError?: (error: Error) => void, // Flush error callback
});Node.js (NodeTracker)
new NodeTracker({
// Required
endpoint: string, // API base URL (no trailing slash)
apiKey: string, // Bearer token (trk_...)
// Optional
shopId?: string, // Default shop ID for all events
flushInterval?: number, // Auto-flush interval in ms (default: 5000)
flushSize?: number, // Queue threshold for immediate flush (default: 20)
maxQueueSize?: number, // Max queue before dropping oldest (default: 1000)
autoDevice?: boolean, // Auto device detection (default: true, sets deviceType to "server")
userAgent?: string, // UA string from HTTP request (enables browser/OS parsing)
onError?: (error: Error) => void, // Flush error callback
});Fingerprinting is not available in Node.js. Device type defaults to "server". Pass userAgent to parse browser/OS info from incoming HTTP requests.
API
tracker.track(eventName, properties?, options?)
Queue a tracking event. Synchronous, never throws.
tracker.track(
"click",
{ target: "buy_button" },
{
shopId: "shop_002", // Override default
deviceType: "server", // Override auto-detection
timestamp: new Date().toISOString(),
},
);tracker.trackVisible(target, eventName, properties?, options?)
Track when an element becomes visible. Returns an unsubscribe function.
| Option | Type | Default | Description |
| ----------- | ------- | ------- | ---------------------------------------------- |
| threshold | number | 0.5 | Fraction of element that must be visible (0-1) |
| dwell | number | 500 | Milliseconds element must stay visible |
| once | boolean | true | Auto-unsubscribe after first fire |
const unsub = tracker.trackVisible(
"#product-card",
"impression",
{},
{
threshold: 0.75,
dwell: 1000,
once: true,
},
);
unsub(); // Stop trackingtracker.trackClick(target, eventName, properties?, options?)
Track element clicks. Returns an unsubscribe function.
| Option | Type | Default | Description |
| ------ | ------- | ------- | ---------------------------------- |
| once | boolean | false | Auto-unsubscribe after first click |
tracker.flush()
Force-send all queued events. Returns a Promise.
tracker.pending
Number of events currently queued.
tracker.destroy()
Flush remaining events, stop timers, remove all listeners.
tracker.listEvents(params?)
Query events from the API. Throws TrustshopError on HTTP errors.
const result = await tracker.listEvents({
page: 0,
perPage: 20,
eventName: "purchase",
q: "product", // Full-text search
from: "2025-01-01",
to: "2025-01-31",
});
// result.events: EventRecord[]tracker.getEvent(id)
Fetch a single event by UUID. Throws TrustshopError on HTTP errors.
How It Works
- Queueing:
track()pushes events to an in-memory queue (never blocks or throws) - Auto-flush: Every
flushIntervalms (viarequestIdleCallback) or when queue reachesflushSize - Batch delivery: Sends up to 100 events per
POST /api/events/batchrequest - Page unload: Uses
sendBeacononvisibilitychange/pagehide(falls back tofetchwithkeepalive) - Retry: Failed events are re-queued at the front for the next flush
- Fingerprinting: FingerprintJS with SHA-256 fallback (user agent + screen + timezone + hardware)
- Device detection: Parses
navigator.userAgentfor browser, OS, and device type
Development
# Build (ESM + IIFE bundle)
pnpm build
# Watch mode
pnpm devBuild Outputs
| Output | Format | Entry | Purpose |
| ------------------------ | ------ | ------------------ | -------------------- |
| dist/index.js | ESM | src/index.ts | Browser npm import |
| dist/index.d.ts | Types | — | Browser types |
| dist/browser.bundle.js | IIFE | src/browser.ts | <script> tag usage |
| dist/node/index.js | ESM | src/node-entry.ts| Node.js ESM import |
| dist/node/index.cjs | CJS | src/node-entry.ts| Node.js require() |
| dist/node/index.d.ts | Types | — | Node.js types |
