GetuAI Attribution V2 SDK for client-side tracking
npm install getu-attribution-v2-sdkA JavaScript SDK for tracking user attribution and conversion events in web applications.
- Features
- Installation
- Quick Start
- Configuration
- User ID Management
- Event Tracking
- Auto-Tracking
- SPA Support
- Cross-Domain UTM
- Attribution Data
- Storage
- Offline Support
- API Reference
- TypeScript Support
- Browser Support
---
| Feature | Description |
| ------------------------- | -------------------------------------------------------------------------- |
| ๐ฏ UTM Tracking | Automatic capture and storage of UTM parameters from URLs |
| ๐ Cross-Domain UTM | Automatic UTM parameter passing to external links |
| ๐ฆ Event Batching | Efficient batch processing of events with configurable intervals |
| ๐ด Offline Support | Queue events locally when offline, sync when connection restores |
| ๐ SPA Support | Automatic page view tracking for Single Page Applications |
| โก Immediate Events | Critical events (purchase, login, signup, audit approved) sent immediately |
| ๐ Session Management | Tracks user sessions with configurable timeout |
| ๐งน Auto Clean UTM | Removes UTM parameters from URL after capture |
| ๐ Page View Debounce | Prevents duplicate page view events within configurable interval |
| ๐ TypeScript | Full TypeScript support with type definitions |
---
``html`
src="https://unpkg.com/getu-attribution-v2-sdk/dist/getuai-attribution.min.js"
data-api-key="your_api_key_here"
>
`bash`
npm install getu-attribution-v2-sdk
---
The SDK auto-initializes when loaded with a data-api-key attribute:
`html`
src="https://unpkg.com/getu-attribution-v2-sdk/dist/getuai-attribution.min.js"
data-api-key="your_api_key_here"
data-auto-track-page-view="true"
data-debug="true"
>
`javascript
import { init, trackPageView, EventType } from "getu-attribution-v2-sdk";
// Initialize SDK
await init({
apiKey: "your_api_key_here",
autoTrackPageView: true,
enableDebug: true,
});
// Track custom event
await trackPageView({ category: "homepage" });
`
---
| Attribute | Type | Default | Description |
| --------------------------- | ------- | --------------------------------------------- | --------------------------------------------- |
| data-api-key | string | required | Your GetuAI API key |data-api-endpoint
| | string | https://attribution.getu.ai/attribution/api | API endpoint URL |data-debug
| | boolean | false | Enable debug logging |data-auto-track
| | boolean | false | Enable auto-tracking (forms, links) |data-auto-track-page-view
| | boolean | false | Enable auto page view tracking (includes SPA) |data-batch-size
| | number | 100 | Number of events per batch |data-batch-interval
| | number | 2000 | Batch interval in milliseconds |data-auto-clean-utm
| | boolean | true | Remove UTM params from URL after capture |data-user-id
| | string | - | Initial user ID |
`typescript
interface SDKConfig {
// Required
apiKey: string;
// API Settings
apiEndpoint?: string; // Default: "https://attribution.getu.ai/attribution/api"
// Batch Settings
batchSize?: number; // Default: 100
batchInterval?: number; // Default: 2000 (ms)
maxRetries?: number; // Default: 3
retryDelay?: number; // Default: 1000 (ms)
// Auto-Tracking
autoTrack?: boolean; // Default: false - Enable form/link tracking
autoTrackPageView?: boolean; // Default: false - Enable page view + SPA tracking
// Session
sessionTimeout?: number; // Default: 1800000 (30 minutes in ms)
// Cross-Domain UTM
enableCrossDomainUTM?: boolean; // Default: true
crossDomainUTMParams?: string[]; // Default: ["utm_source", "utm_medium", "utm_campaign", "utm_term", "utm_content"]
excludeDomains?: string[]; // Default: [] - Domains to exclude from UTM passing
// URL Management
autoCleanUTM?: boolean; // Default: true - Remove UTM from URL after capture
// Page View
pageViewDebounceInterval?: number; // Default: 5000 (ms) - Debounce interval for same page
// User ID
userId?: string; // Initial user ID to set on initialization
// Debug
enableDebug?: boolean; // Default: false
}
`
`javascript`
await init({
apiKey: "your_api_key_here",
apiEndpoint: "https://your-api.com/attribution/api",
batchSize: 50,
batchInterval: 3000,
maxRetries: 5,
retryDelay: 2000,
autoTrack: true,
autoTrackPageView: true,
sessionTimeout: 60 60 1000, // 1 hour
enableCrossDomainUTM: true,
crossDomainUTMParams: ["utm_source", "utm_medium", "utm_campaign"],
excludeDomains: ["google.com", "facebook.com"],
autoCleanUTM: true,
pageViewDebounceInterval: 3000,
userId: "user_123", // Optional: Set initial user ID
enableDebug: true,
});
---
The SDK automatically manages user IDs and includes them in all tracked events.
#### During Initialization
You can set the user ID when initializing the SDK:
`javascript
// Via script tag
src="https://unpkg.com/getu-attribution-v2-sdk/dist/getuai-attribution.min.js"
data-api-key="your_api_key_here"
data-user-id="user_123"
>;
// Via configuration object
await init({
apiKey: "your_api_key_here",
userId: "user_123",
});
`
#### Programmatically Set User ID
You can set or update the user ID at any time:
`javascript
import { setUserId } from "getu-attribution-v2-sdk";
// Set user ID (e.g., after user login)
setUserId("user_123");
`
`javascript
import { getUserId } from "getu-attribution-v2-sdk";
const userId = getUserId();
console.log("Current user ID:", userId); // "user_123" or null
`
`javascript
import { removeUserId } from "getu-attribution-v2-sdk";
// Remove user ID (e.g., after user logout)
removeUserId();
`
Once a user ID is set, it will automatically be included in all tracked events, even if you don't explicitly pass it:
`javascript
// User ID is already set via setUserId("user_123")
// This will automatically include user_123 in the event
await trackPageView({ category: "homepage" });
// Explicit user ID parameter will override the stored one
await trackPageView({ category: "homepage" }, "different_user_456");
`
---
`typescript
enum EventType {
// Pre-conversion signals
PAGE_VIEW = "page_view",
PAGE_CLICK = "page_click",
VIDEO_PLAY = "video_play",
// Registration funnel
FORM_SUBMIT = "form_submit",
EMAIL_VERIFICATION = "email_verification",
// Login flow
LOGIN = "login",
// Signup flow
SIGNUP = "signup",
// Purchase funnel
PRODUCT_VIEW = "product_view",
ADD_TO_CART = "add_to_cart",
PURCHASE = "purchase",
// Post-conversion / back-office conversion
AUDIT_APPROVED = "audit_approved",
}
`
These events are sent immediately (not batched):
- PURCHASELOGIN
- SIGNUP
- FORM_SUBMIT
- EMAIL_VERIFICATION
- AUDIT_APPROVED
-
`javascript
// Basic
await trackPageView();
// With custom data
await trackPageView({
category: "product",
section: "electronics",
});
// With user ID
await trackPageView({ category: "dashboard" }, "user_123");
`
`javascript
// Basic
await trackPageClick();
// With click context
await trackPageClick("user_123", {
element_id: "btn_signup",
element_type: "button",
element_text: "Sign Up",
position: { x: 120, y: 360 },
});
`
Method 1: Traditional format (user_id required)
`javascript`
await trackPurchase(
"user_123", // tracking_user_id (required)
99.99, // revenue
Currency.USD, // currency (optional, default: USD)
{
// purchaseData (optional)
product_id: "prod_123",
product_name: "Premium Plan",
quantity: 1,
}
);
Method 2: Auto user ID format (object parameter, user_id optional)
`javascript
// Auto-use stored user ID
await trackPurchaseAuto({
revenue: 99.99,
currency: Currency.USD, // optional
purchaseData: {
product_id: "prod_123",
product_name: "Premium Plan",
quantity: 1,
},
// tracking_user_id is optional - will use stored user ID if not provided
});
// Or explicitly provide user ID
await trackPurchaseAuto({
revenue: 99.99,
tracking_user_id: "user_123", // optional, will use stored if not provided
purchaseData: { product_id: "prod_123" },
});
`
Method 1: Traditional format (user_id required)
`javascript`
await trackLogin("user_123", {
method: "email",
provider: "google",
});
Method 2: Auto user ID format (object parameter, user_id optional)
`javascript
// Auto-use stored user ID
await trackLoginAuto({
loginData: {
method: "email",
provider: "google",
},
// tracking_user_id is optional - will use stored user ID if not provided
});
// Or explicitly provide user ID
await trackLoginAuto({
tracking_user_id: "user_123", // optional
loginData: { method: "email" },
});
`
Method 1: Traditional format (user_id required)
`javascript`
await trackSignup("user_123", {
method: "email",
referral_code: "REF123",
});
Method 2: Auto user ID format (object parameter, user_id optional)
`javascript
// Auto-use stored user ID
await trackSignupAuto({
signupData: {
method: "email",
referral_code: "REF123",
},
// tracking_user_id is optional - will use stored user ID if not provided
});
// Or explicitly provide user ID
await trackSignupAuto({
tracking_user_id: "user_123", // optional
signupData: { method: "email" },
});
`
`javascript`
await trackFormSubmit("user_123", {
form_id: "contact_form",
form_type: "contact",
});
`javascript
// Basic
await trackVideoPlay();
// With user ID
await trackVideoPlay("user_123");
// With custom data
await trackVideoPlay("user_123", {
video_id: "video_123",
video_title: "Introduction Video",
duration: 120,
position: 30,
});
`
Method 1: Traditional format (user_id required)
`javascript`
await trackEmailVerification("user_123", {
email: "user@example.com",
verification_method: "email_link",
});
Method 2: Auto user ID format (object parameter, user_id optional)
`javascript
// Auto-use stored user ID
await trackEmailVerificationAuto({
verificationData: {
email: "user@example.com",
verification_method: "email_link",
},
// tracking_user_id is optional - will use stored user ID if not provided
});
// Or explicitly provide user ID
await trackEmailVerificationAuto({
tracking_user_id: "user_123", // optional
verificationData: { email: "user@example.com" },
});
`
Track an audit approval conversion event. Sent immediately.
`javascript
import { trackAuditApproved } from "getu-attribution-v2-sdk";
await trackAuditApproved("user_123", {
audit_id: "audit_987",
reviewer: "ops_team",
});
`
The following functions support auto user ID with object parameter format:
- trackPurchaseAuto(options) - Purchase tracking with optional user IDtrackLoginAuto(options)
- - Login tracking with optional user IDtrackSignupAuto(options)
- - Signup tracking with optional user IDtrackEmailVerificationAuto(options)
- - Email verification tracking with optional user ID
Important Notes:
- If tracking_user_id is not provided in options and no user ID is stored, these functions will log an error and return without tracking the eventsetUserId()
- Always set user ID using before calling these functions, or provide tracking_user_id in the optionstrackPurchase
- The traditional functions (, trackLogin, etc.) still require tracking_user_id as the first parameter
`javascript
// Basic
await trackProductView();
// With user ID
await trackProductView("user_123");
// With product data
await trackProductView("user_123", {
product_id: "prod_123",
product_name: "Widget",
category: "electronics",
price: 29.99,
});
`
`javascript
// Basic
await trackAddToCart();
// With user ID
await trackAddToCart("user_123");
// With cart data
await trackAddToCart("user_123", {
product_id: "prod_123",
product_name: "Widget",
quantity: 2,
price: 29.99,
});
`
`javascript`
await trackEvent(
EventType.ADD_TO_CART,
{
product_id: "prod_123",
product_name: "Widget",
price: 29.99,
quantity: 2,
},
"user_123", // tracking_user_id (optional)
29.99, // revenue (optional)
Currency.USD // currency (optional)
);
---
When autoTrack: true, the SDK automatically tracks:
#### Form Submissions
- Captures all form field values (with password masking)
- Includes form metadata (id, action, method)
- Handles checkboxes, radio buttons, multi-select, file inputs
- Fallback field collection: For form fields without name attribute, SDK will use fallback keys:name
- Priority: attributeid_{id}
- Fallback 1: (if field has id)aria_{aria-label}
- Fallback 2: (if field has aria-label)ph_{placeholder}_{index}
- Fallback 3: (if field has placeholder)field_{index}
- Fallback 4: (as last resort)
#### External Link Clicks
- Adds UTM parameters to external links
- Respects excludeDomains configuration
When autoTrackPageView: true, the SDK:
1. Initial Page View: Tracks page view on SDK initialization
2. SPA Route Changes: Automatically tracks navigation via:
- history.pushState()history.replaceState()
- pageViewDebounceInterval
- Browser back/forward (popstate)
3. Debouncing: Prevents duplicate tracking within
---
Single Page Application support is automatically enabled when autoTrackPageView: true.
`
User visits /home
โโโ SDK tracks PAGE_VIEW for /home
User clicks link to /products
โโโ React Router calls history.pushState()
โโโ SDK detects route change
โโโ SDK tracks PAGE_VIEW for /products (after 100ms delay for title update)
User clicks browser back button
โโโ Browser fires popstate event
โโโ SDK detects route change
โโโ SDK tracks PAGE_VIEW for /home
`
The SDK intercepts:
- history.pushState() - Standard navigationhistory.replaceState()
- - URL replacementpopstate
- event - Browser back/forward
Only tracks when pathname + search actually changes:
`javascript
// These are considered different paths:
"/products"
"/products?category=electronics"
"/products/123"
// These are considered the same (no duplicate tracking):
"/products" -> "/products"
`
---
When users click external links, UTM parameters are automatically appended:
`
User visits your site with ?utm_source=google&utm_medium=cpc
โโโ UTM params stored in localStorage
User clicks link to https://partner-site.com/page
โโโ SDK modifies link to:
https://partner-site.com/page?utm_source=google&utm_medium=cpc
`
`javascript`
await init({
apiKey: "your_api_key",
enableCrossDomainUTM: true, // Default: true
crossDomainUTMParams: [
// Which params to pass
"utm_source",
"utm_medium",
"utm_campaign",
],
excludeDomains: [
// Don't pass UTM to these domains
"google.com",
"facebook.com",
"twitter.com",
],
});
`javascript
// Add UTM to any URL
const enhancedURL = addUTMToURL("https://example.com/page");
// Result: "https://example.com/page?utm_source=google&utm_medium=cpc"
// Get current UTM parameters
const utmParams = getCurrentUTMParams();
// Result: { utm_source: "google", utm_medium: "cpc", utm_campaign: "summer" }
`
---
`typescript
interface AttributionData {
firstTouch: UTMData; // First attribution touchpoint
lastTouch: UTMData; // Most recent touchpoint
touchpoints: UTMData[]; // All touchpoints history
expiresAt: number; // Expiration timestamp
}
interface UTMData {
utm_source?: string;
utm_medium?: string;
utm_campaign?: string;
utm_term?: string;
utm_content?: string;
timestamp: number;
}
`
`javascript
const attribution = getAttributionData();
if (attribution) {
console.log("First Touch:", attribution.firstTouch);
console.log("Last Touch:", attribution.lastTouch);
console.log("All Touchpoints:", attribution.touchpoints);
}
`
A new touchpoint is recorded when:
- utm_source changes, ORutm_campaign
- changes
---
| Key | Content | Retention |
| ---------------------- | -------------------- | ------------- |
| attribution_utm_data | UTM attribution data | 30 days |attribution_session
| | Session information | Session-based |
| Store | Content | Retention |
| -------- | ----------- | --------------------- |
| events | Event queue | 7 days (auto cleanup) |
- UTM Data: Expired data removed on next access
- Events: Old events (>7 days) cleaned up periodically
- Quota Exceeded: Oldest 20% of data removed automatically
---
`
User goes offline
โโโ Events queued in IndexedDB
User tracks events
โโโ Events stored locally
User goes online
โโโ SDK detects connection restore
โโโ Queued events sent to server
Page unload
โโโ SDK attempts to flush pending events
`
- Failed requests retry with exponential backoff
- Default: 3 retries with 1s base delay
- Delay: baseDelay * 2^attemptNumber
---
#### init(config: SDKConfig): Promise
Initialize the SDK with configuration.
`javascript`
const sdk = await init({ apiKey: "your_key" });
#### getSDK(): AttributionSDK | null
Get the current SDK instance.
`javascript`
const sdk = getSDK();
if (sdk) {
// SDK is initialized
}
#### waitForSDK(): Promise
Wait for SDK initialization (useful with auto-init).
`javascript`
const sdk = await waitForSDK();
#### trackEvent(eventType, eventData?, tracking_user_id?, revenue?, currency?): Promise
Track a custom event.
#### trackPageView(pageData?, tracking_user_id?): Promise
Track a page view event.
#### trackPurchase(tracking_user_id, revenue, currency?, purchaseData?): Promise
Track a purchase event (sent immediately).
#### trackLogin(tracking_user_id, loginData?): Promise
Track a login event (sent immediately).
#### trackSignup(tracking_user_id, signupData?): Promise
Track a signup event (sent immediately).
#### trackFormSubmit(tracking_user_id?, formData?): Promise
Track a form submission event (sent immediately).
#### trackVideoPlay(tracking_user_id?, videoData?): Promise
Track a video play event.
`javascript`
await trackVideoPlay("user_123", {
video_id: "video_123",
video_title: "Introduction Video",
duration: 120,
});
#### trackEmailVerification(tracking_user_id, verificationData?): Promise
Track an email verification event (sent immediately).
`javascript`
await trackEmailVerification("user_123", {
email: "user@example.com",
verification_method: "email_link",
});
#### trackProductView(tracking_user_id?, productData?): Promise
Track a product view event.
`javascript`
await trackProductView("user_123", {
product_id: "prod_123",
product_name: "Widget",
category: "electronics",
});
#### trackAddToCart(tracking_user_id?, cartData?): Promise
Track an add to cart event.
`javascript`
await trackAddToCart("user_123", {
product_id: "prod_123",
product_name: "Widget",
quantity: 2,
price: 29.99,
});
#### getAttributionData(): AttributionData | null
Get current attribution data.
#### addUTMToURL(url: string): string
Add current UTM parameters to a URL.
#### getCurrentUTMParams(): Record
Get current UTM parameters as object.
#### flush(): Promise
Flush all pending events to the server.
#### getStatus(): SDKStatus | null
Get SDK status including initialization state, session info, queue size, and SPA tracking status.
`javascript`
const status = getStatus();
// {
// initialized: true,
// session: { sessionId: "...", startTime: ..., lastActivity: ..., pageViews: 0 },
// queueSize: 5,
// online: true,
// crossDomainUTM: {
// enabled: true,
// currentParams: { utm_source: "google" }
// },
// spaTracking: {
// enabled: true,
// currentPath: "/products"
// }
// }
#### destroy(): void
Destroy SDK instance and clean up resources.
---
`javascript
// Access via window.getuaiSDK namespace
await window.getuaiSDK.init({ apiKey: "your_key" });
await window.getuaiSDK.trackPageView();
await window.getuaiSDK.trackPurchase("user_123", 99.99);
// Access enums
const eventType = window.getuaiSDK.EventType.PURCHASE;
const currency = window.getuaiSDK.Currency.USD;
`
`javascript
import { AttributionSDK, EventType } from "getu-attribution-v2-sdk";
// Use static methods
await AttributionSDK.init({ apiKey: "your_key" });
await AttributionSDK.trackEvent(EventType.PAGE_VIEW);
await AttributionSDK.trackPurchase("user_123", 99.99);
const attribution = AttributionSDK.getAttributionData();
const status = AttributionSDK.getStatus();
`
`javascript
import { AttributionSDK } from "getu-attribution-v2-sdk";
const sdk = new AttributionSDK({
apiKey: "your_key",
enableDebug: true,
});
await sdk.init();
await sdk.trackPageView();
`
`javascript
// Listen for SDK ready
window.addEventListener("getuaiSDKReady", (event) => {
console.log("SDK initialized:", event.detail.sdk);
});
// Listen for SDK errors
window.addEventListener("getuaiSDKError", (event) => {
console.error("SDK error:", event.detail.error);
});
`
---
`typescript
import {
init,
trackEvent,
EventType,
Currency,
type SDKConfig,
type EventData,
type AttributionData,
} from "getu-attribution-v2-sdk";
const config: SDKConfig = {
apiKey: "your_api_key_here",
enableDebug: true,
autoTrackPageView: true,
};
await init(config);
// Type-safe event tracking
await trackEvent(
EventType.PURCHASE,
{ product_id: "123" },
"user_123",
99.99,
Currency.USD
);
// Type-safe attribution data
const attribution: AttributionData | null = getAttributionData();
`
---
| Browser | Minimum Version |
| ------- | --------------- |
| Chrome | 50+ |
| Firefox | 50+ |
| Safari | 10+ |
| Edge | 79+ |
- localStorageIndexedDB
- history.pushState/replaceState
- fetch
- Promise
-
---
Enable debug logging to see detailed SDK activity:
`html`
`javascript`
// Via config
await init({
apiKey: "your_key",
enableDebug: true,
});
``
[GetuAI Info] ๐ GetuAI Attribution SDK initialized successfully
[GetuAI Info] ๐ Auto track page view enabled (including SPA route tracking)
[GetuAI Debug] ๐ [SPA] Route change detected (pushState): /home -> /products
[GetuAI Debug] โ
[SPA] Page view tracked for: /products
[GetuAI Info] UTM data extracted and stored successfully
---
`javascript``
try {
await trackPurchase("user_123", 99.99, Currency.USD, {
product_id: "prod_123",
});
} catch (error) {
console.error("Failed to track purchase:", error);
// Event will be queued for retry automatically
}
Events that fail to send are:
1. Stored in IndexedDB
2. Retried with exponential backoff
3. Sent when connection restores
---
MIT