@truxl/javascript-sdk
v1.0.0
Published
Truxl analytics JavaScript SDK for browser event tracking
Downloads
167
Readme
Truxl JavaScript SDK
Lightweight browser analytics SDK for Truxl — track user events, identify users, and capture behavioral data with zero dependencies.
- ~8 KB minified (UMD)
- Automatic page view tracking
- Optional autocapture (clicks, scroll, forms, rage clicks, dead clicks)
- Event batching with retry
- HMAC-SHA256 request signing
- TypeScript support
Quick Start
Option 1: Script Tag (CDN)
Add this to your HTML <head>:
<script src="https://sdk.truxl.com/javascript/truxl-0.1.0.umd.js"></script>Then initialize:
<script>
var truxl = new window.truxl.TruxlClient({
projectToken: 'YOUR_PROJECT_TOKEN',
clientSecret: 'YOUR_CLIENT_SECRET',
apiEndpoint: 'https://ingestion.api.truxl.com',
});
// Track an event
truxl.track('page_view', { page: '/home' });
</script>Option 2: npm
npm install @truxl/javascript-sdkimport { TruxlClient } from '@truxl/javascript-sdk';
const truxl = new TruxlClient({
projectToken: 'YOUR_PROJECT_TOKEN',
clientSecret: 'YOUR_CLIENT_SECRET',
apiEndpoint: 'https://ingestion.api.truxl.com',
});Getting Your Credentials
- Log in to the Truxl Client Console (http://localhost:3000)
- Go to Settings > Project Keys
- Copy the Project Token and Client Secret
| Credential | Example | Where to find |
|-----------|---------|---------------|
| Project Token | trxl_proj_demo_123 | Settings > Project Keys |
| Client Secret | demo-secret-key-256bit-... | Settings > Project Keys |
Configuration
const truxl = new TruxlClient({
// Required
projectToken: 'YOUR_PROJECT_TOKEN',
clientSecret: 'YOUR_CLIENT_SECRET',
// Optional
apiEndpoint: 'https://ingestion.api.truxl.com', // Default: https://ingestion.api.stage.truxl.com
batchSize: 20, // Events per batch before auto-flush (default: 20)
flushInterval: 5000, // Auto-flush interval in ms (default: 5000)
maxQueueSize: 10000, // Max queued events (default: 10000)
retryAttempts: 5, // Retry attempts for failed requests (default: 5)
retryBaseDelay: 1000, // Base delay between retries in ms (default: 1000)
transport: 'http', // 'http' or 'websocket' (default: 'http')
track_pageview: true, // Auto-track page views (default: true)
autocapture: false, // Enable autocapture (default: false)
debug: false, // Log to console (default: false)
});All Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| projectToken | string | required | Project token from Client Console |
| clientSecret | string | required | Client secret for HMAC request signing |
| apiEndpoint | string | https://ingestion.api.stage.truxl.com | Ingestion Service URL |
| batchSize | number | 20 | Events per batch before auto-flush |
| flushInterval | number | 5000 | Auto-flush interval in milliseconds |
| maxQueueSize | number | 10000 | Max events in queue (oldest dropped when full) |
| retryAttempts | number | 5 | Max retries for transient failures |
| retryBaseDelay | number | 1000 | Base delay (ms) between retries |
| transport | 'http' | 'websocket' | 'http' | Transport protocol |
| track_pageview | boolean | true | Automatically track page views on load and URL changes |
| autocapture | boolean | AutocaptureConfig | false | Enable automatic event capture |
| debug | boolean | false | Log events and config to console |
Core API
track(eventName, properties?)
Track a custom event with optional properties.
// Simple event
truxl.track('button_click');
// Event with properties
truxl.track('add_to_cart', {
product_id: 'sku-42',
product_name: 'Running Shoes',
price: 129.99,
quantity: 1,
category: 'footwear',
});
// Page-specific event
truxl.track('search', {
query: 'running shoes',
result_count: 24,
page: '/search',
});identify(distinctId, userProperties?)
Link events to a known user. Call after login or signup. All subsequent events are associated with this user.
// After login
truxl.identify('user-123', {
email: '[email protected]',
name: 'John Doe',
plan: 'pro',
});
// Minimal identify
truxl.identify('user-123');reset()
Clear the user identity. Call on logout. Events after reset are tracked anonymously (device-level).
// On logout
truxl.reset();flush()
Force-send all queued events immediately. Useful before navigation or page unload.
truxl.flush();destroy()
Tear down the SDK — stops autocapture, clears timers, closes transport.
truxl.destroy();Autocapture
Enable automatic event capture for clicks, scroll depth, form submissions, and more — no manual instrumentation required.
Enable All Autocapture
const truxl = new TruxlClient({
projectToken: 'YOUR_TOKEN',
clientSecret: 'YOUR_SECRET',
autocapture: true, // Enable all autocapture features
});Customize Autocapture
const truxl = new TruxlClient({
projectToken: 'YOUR_TOKEN',
clientSecret: 'YOUR_SECRET',
autocapture: {
pageview: 'full-url', // 'full-url' | 'path-only' | false
click: true, // Track button/link clicks
dead_click: true, // Track clicks with no DOM change
rage_click: true, // Track rapid repeated clicks (3+ in 1s)
input: true, // Track input field changes (sensitive fields redacted)
scroll: true, // Track scroll depth (25%, 50%, 75%, 100%)
submit: true, // Track form submissions
capture_text_content: false, // Capture element text (default: false for privacy)
},
});Autocapture Events
| Event | Trigger | Key Properties |
|-------|---------|----------------|
| $pageview | Page load, URL change (pushState/popState) | $url, $path, $referrer, $title |
| $autocapture_click | Click on <a>, <button>, or role="button" | $element_tag, $element_id, $element_classes |
| $dead_click | Click with no DOM mutation within 1 second | $element_tag, $element_id |
| $rage_click | 3+ clicks on same element within 1 second | $element_tag, $click_count |
| $autocapture_input | Input field value change | $element_tag, $element_type, $value_redacted |
| $autocapture_scroll | Scroll milestone reached | $scroll_depth (25/50/75/100) |
| $form_submit | Form submission | $form_id, $form_action, $form_fields |
Privacy
- Sensitive fields are automatically redacted — passwords, credit cards, SSN, tokens, and hidden fields are never captured
- Text content is off by default — set
capture_text_content: trueto opt in - Input values: only the value length is captured when
capture_text_contentis false
Auto-Captured Fields
Every event automatically includes these fields — no manual setup required:
Client-Side (captured by SDK)
| Field | Source | Example |
|-------|--------|---------|
| eventName | track() argument | add_to_cart |
| distinctId | identify() or deviceId | user-123 |
| deviceId | Auto-generated UUID (localStorage) | a1b2c3d4-... |
| sessionId | Auto-generated UUID (sessionStorage) | e5f6g7h8-... |
| timestamp | Date.now() | 1710000000000 |
| browser | User-Agent parsing | Chrome |
| browserVersion | User-Agent parsing | 122.0 |
| os | User-Agent parsing | macOS |
| osVersion | User-Agent parsing | 14.3 |
| deviceType | User-Agent parsing | desktop |
| screenWidth | screen.width | 1920 |
| screenHeight | screen.height | 1080 |
| referrer | document.referrer | https://google.com |
| initialReferrer | First referrer in session | https://google.com |
| searchEngine | Parsed from referrer | google |
| userTimezone | Intl.DateTimeFormat | Asia/Kolkata |
| utmSource | URL query param | google |
| utmMedium | URL query param | cpc |
| utmCampaign | URL query param | spring_sale |
| sdkVersion | Hardcoded | 0.1.0 |
Server-Side (enriched by Ingestion Service)
| Field | Source | Example |
|-------|--------|---------|
| country | GeoIP lookup | India |
| city | GeoIP lookup | Mumbai |
| region | GeoIP lookup | Maharashtra |
| postalCode | GeoIP lookup | 400001 |
| environment | Project key config | production |
Common Integration Patterns
E-Commerce
// Product view
truxl.track('product_view', {
product_id: 'sku-42',
product_name: 'Running Shoes',
price: 129.99,
category: 'footwear',
});
// Add to cart
truxl.track('add_to_cart', {
product_id: 'sku-42',
product_name: 'Running Shoes',
price: 129.99,
quantity: 1,
});
// Remove from cart
truxl.track('remove_from_cart', {
product_id: 'sku-42',
product_name: 'Running Shoes',
});
// Checkout
truxl.track('checkout', {
order_id: 'ord-12345',
total: 259.98,
item_count: 2,
currency: 'USD',
});
// Search
truxl.track('search', {
query: 'running shoes',
result_count: 24,
});User Authentication
// Signup
truxl.identify('user-456', { email: '[email protected]', name: 'Jane Doe' });
truxl.track('signup', { method: 'email' });
// Login
truxl.identify('user-456', { email: '[email protected]' });
truxl.track('login', { method: 'email' });
// Logout
truxl.track('logout');
truxl.reset(); // Clear identity — subsequent events are anonymousSaaS / Feature Usage
// Feature adoption
truxl.track('feature_used', {
feature: 'dark_mode',
action: 'enabled',
});
// Subscription change
truxl.track('plan_upgraded', {
from_plan: 'free',
to_plan: 'pro',
annual: true,
});
// Onboarding
truxl.track('onboarding_step', {
step: 3,
step_name: 'invite_team',
completed: true,
});Content / Media
// Article read
truxl.track('article_read', {
article_id: 'post-789',
title: 'Getting Started with Truxl',
category: 'tutorial',
read_time_seconds: 180,
});
// Video play
truxl.track('video_play', {
video_id: 'vid-001',
title: 'Product Demo',
duration_seconds: 120,
});Data Attribute Tracking
Add data-truxl-event attributes to HTML elements for zero-code event naming with autocapture:
<button data-truxl-event="cta_hero_click" class="btn-primary">
Get Started
</button>When autocapture is enabled and this button is clicked, the $custom_event_name property will include cta_hero_click.
Security
All requests are signed with HMAC-SHA256 using the Web Crypto API:
- SDK serializes the event batch as JSON
- Signs the payload with
clientSecretusing HMAC-SHA256 - Sends the signature in the
X-Truxl-Signatureheader - Ingestion Service verifies the signature server-side
The clientSecret is used only for signing — it is never sent to the server.
How It Works
Browser Ingestion Service Kafka ClickHouse
| | | |
|-- track('event') ---------> | | |
| (batched in queue) | | |
| | | |
|-- flush (batch of events) ->| | |
| + X-Project-Token |-- validate token ------> | |
| + X-Truxl-Signature |-- verify HMAC | |
| |-- check quota | |
| |-- enrich (UA, GeoIP) --> | |
| | |-- Kafka Connect>|
| | | |
|<-- 200 OK ------------------| | events tabletrack()queues events in memory- Events are flushed in batches (by
batchSizeorflushInterval) - Ingestion Service validates the project token, verifies HMAC signature, checks quota
- Events are enriched (browser parsing, GeoIP) and published to Kafka
- Kafka Connect sinks events into ClickHouse for analytics
Building from Source
cd truxl-javascript-sdk
npm install
npm run buildOutput:
dist/
├── truxl.umd.js # UMD bundle (~8 KB minified) — for <script> tags
├── truxl.umd.js.map # Source map
├── truxl.esm.js # ES module — for bundlers (Vite, Webpack)
├── truxl.esm.js.map # Source map
└── index.d.ts # TypeScript declarationsPublishing to S3
# First-time: create bucket
./truxl.sh sdk:setup
# Build + publish
./truxl.sh sdk:publish
# Specific version
./truxl.sh sdk:publish --version 1.0.0S3 structure:
s3://truxl-sdk/javascript/truxl-0.1.0.umd.js # Versioned (immutable, 1-year cache)
s3://truxl-sdk/javascript/truxl-0.1.0.esm.js # ESM version for bundlers
s3://truxl-sdk/javascript/truxl-latest.umd.js # Latest (auto-updated, 5-min cache)CDN URL (CloudFront + Route 53):
https://sdk.truxl.com/javascript/truxl-0.1.0.umd.jsBrowser Support
| Browser | Version | |---------|---------| | Chrome | 63+ | | Firefox | 57+ | | Safari | 11.1+ | | Edge | 79+ |
Requires: crypto.subtle (Web Crypto API), localStorage, sessionStorage, fetch.
License
MIT
