Skip to content

treasure-data/td-web-sdk

Repository files navigation

Treasure Data Web SDK

Modern, TypeScript-first analytics SDK for browser event tracking with comprehensive type safety and plugin architecture.

Quick Start

Install

NPM (Recommended)

npm install td-web-sdk

CDN Script

<script type="text/javascript">
!function(t,e){if(void 0===e[t]){e[t]=function(){e[t].clients.push(this),this._init=[Array.prototype.slice.call(arguments)]},e[t].clients=[];for(var r=function(t){return function(){return this["_"+t]=this["_"+t]||[],this["_"+t].push(Array.prototype.slice.call(arguments)),this}},s=["set","collectTags","blockEvents","unblockEvents","setSignedMode","setAnonymousMode","fetchServerCookie","fetchGlobalID","fetchUserSegments","fetchPersonalization","resetUUID","addRecord","trackEvent","trackPageview","trackClicks","ready"],c=0;c<s.length;c++){var o=s[c];e[t].prototype[o]=r(o)}var n=document.createElement("script");n.type="text/javascript",n.async=!0,n.src=("https:"===document.location.protocol?"https:":"http:")+"//cdn.treasuredata.com/sdk/web/0.1/td-sdk.min.js";var i=document.getElementsByTagName("script")[0];i.parentNode.insertBefore(n,i)}}("Treasure",this);
</script>

First Event

// TypeScript
import Treasure from 'td-web-sdk'

const td = new Treasure({
  writeKey: 'your-write-key',
  database: 'your-database'
})

// Track your first event
td.trackEvent('user_actions', {
  action: 'click',
  button: 'signup'
})
// JavaScript (Node.js/CommonJS)
const Treasure = require('td-web-sdk').default

// Or ES modules
import Treasure from 'td-web-sdk'

const td = new Treasure({
  writeKey: 'your-write-key', 
  database: 'your-database'
})

Key Features

  • TypeScript-first: Full type safety and IntelliSense support
  • Modern Architecture: Composable plugin-based system
  • Privacy Compliance: GDPR-ready with privacy controls
  • Automatic UTM Collection: UTM parameters captured on init
  • Cross-device: Global ID and server-side cookies for ITP compliance
  • Zero Dependencies: Lightweight, self-contained

Common Use Cases

Page View Tracking

// Track page view
td.trackPageview('pageviews')

// With success/error callbacks
td.trackPageview('pageviews', 
  (response) => console.log('Pageview tracked!'),
  (error) => console.error('Failed:', error)
)

// With personalization: configure it once on the constructor. When set, every
// trackEvent/trackPageview call fetches personalization INSTEAD of ingesting the
// event (the call no longer records to your database — see below)
const td = new Treasure({
  writeKey: 'your-write-key',
  database: 'your-database',
  personalization: {
    endpoint: 'personalization.example.com',
    token: 'personalization_token',
    database: 'personalization_db'  // optional; defaults to the main `database`
  }
})

// The personalization table comes from the tracking call ('pageviews' here),
// and the request payload is the event data (track values + globals + record)
td.trackPageview('pageviews',
  (response) => console.log('Personalization fetched!'),
  (error) => console.error('Failed:', error)
)

Event Tracking

// Basic event
td.trackEvent('events', {
  event_type: 'purchase',
  item_id: 'SKU-123',
  revenue: 29.99
})

// With success/error callbacks
td.trackEvent('button_clicks', { button: 'header_cta' }, 
  (response) => console.log('Tracked!'),
  (error) => console.error('Failed:', error)
)

Global Properties

// Set user properties for all events
td.set('$global', 'user_id', '12345')
td.set('$global', 'plan', 'premium')

// Set table-specific defaults
td.set('purchases', 'currency', 'USD')

// Multiple properties at once
td.set('$global', {
  user_id: '12345',
  plan: 'premium',
  signup_date: '2024-01-15'
})

Automatic Click Tracking

// Track all clicks on buttons and links
td.trackClicks()

// Custom configuration
td.trackClicks({
  tableName: 'ui_interactions',
  element: document.getElementById('main-content')
})

UTM Parameter Collection

// Collect UTM parameters from URL
const utmParams = td.collectUTMParameters()
console.log(utmParams) // { utm_source: 'google', utm_campaign: 'summer2024' }

// Get previously collected UTMs
const storedUtms = td.getUTMParameters()

Privacy & Consent Management

Signed vs Anonymous Mode

const td = new Treasure({ 
  writeKey: 'key', 
  database: 'db',
  startInSignedMode: false  // Default: anonymous mode
})

// Anonymous mode (default) - no PII collected
td.setAnonymousMode()
td.trackEvent('events', { action: 'view' })
// Sends: { action: 'view', td_version: '1.0.0' }
// Omits: td_client_id, td_ip, td_global_id

// Signed mode - PII collection enabled  
td.setSignedMode()
td.trackEvent('events', { action: 'purchase' })
// Sends: { action: 'purchase', td_client_id: 'uuid', td_ip: '192.168.1.1' }

Event Blocking

// Temporarily block all events
td.blockEvents()
td.trackEvent('blocked', {}) // Not sent

// Resume tracking
td.unblockEvents() 
td.trackEvent('tracked', {}) // Sent normally

// Check status
if (td.areEventsBlocked()) {
  console.log('Tracking is currently blocked')
}

Privacy Control Example

const td = new Treasure({ writeKey: 'key', database: 'db' })

// Programmatically manage privacy based on user preferences
function handleUserPrivacyChoice(privacyLevel) {
  switch (privacyLevel) {
    case 'full_tracking':
      td.unblockEvents()
      td.setSignedMode()
      break
    case 'anonymous_only':
      td.unblockEvents() 
      td.setAnonymousMode()
      break
    case 'no_tracking':
      td.blockEvents()
      break
  }
}

// Example: User clicks privacy preference buttons
document.getElementById('accept-all').onclick = () => handleUserPrivacyChoice('full_tracking')
document.getElementById('essential-only').onclick = () => handleUserPrivacyChoice('anonymous_only')
document.getElementById('reject-all').onclick = () => handleUserPrivacyChoice('no_tracking')

Advanced Features

Global ID (Cross-device Tracking)

// 1. Enable Global ID collection
td.set('$global', 'td_global_id', 'td_global_id')

// 2. Switch to signed mode
td.setSignedMode()

// 3. Fetch Global ID
td.fetchGlobalID(
  (globalId) => {
    console.log('Global ID:', globalId)
    // Use for cross-device analytics
  },
  (error) => console.error('Failed to get Global ID:', error),
  false, // forceFetch
  { 
    domain: '.yourdomain.com',
    secure: true,
    sameSite: 'None'
  }
)

Server-Side Cookies (ITP Compliance)

const td = new Treasure({
  writeKey: 'key',
  database: 'db',
  useServerSideCookie: true,
  sscDomain: 'yourdomain.com'
})

td.fetchServerCookie(
  (serverId) => console.log('Server ID:', serverId),
  (error) => console.error('Server cookie failed:', error)
)

User Segmentation

// Fetch user segments for personalization
td.fetchUserSegments(
  'audience_token_abc123',
  (segments) => {
    segments.forEach(segment => {
      console.log('Segment:', segment.values)
      console.log('Attributes:', segment.attributes)
    })
  },
  (error) => console.error('Segmentation failed:', error)
)

// With custom keys
td.fetchUserSegments({
  audienceToken: ['token1', 'token2'],
  keys: { user_id: '12345', email: 'user@example.com' }
}, successCallback, errorCallback)

Personalization & In-Browser Messaging

// Manual personalization fetch
td.fetchPersonalization({
  endpoint: 'personalization.example.com',
  database: 'recommendations_db', 
  table: 'user_offers',
  token: 'p13n_token_123'
}, {
  user_id: '12345',
  page_type: 'product_detail',
  product_category: 'electronics'
}, (response) => {
  console.log('Personalization response:', response)
})

// Personalization driven by tracking calls
// Configure personalization once on the constructor...
const td = new Treasure({
  writeKey: 'your-write-key',
  database: 'your-database',
  personalization: {
    endpoint: 'personalization.example.com',
    token: 'p13n_token_123',
    database: 'recommendations_db'  // optional; defaults to the main `database`
  }
})

// ...then trackEvent and trackPageview fetch personalization instead of
// ingesting the event. The personalization table is the tracking call's table,
// and the request payload is the event data ($global + table defaults + track
// values + record) — not recorded to your database.
td.trackEvent('events', { action: 'view' })
td.trackPageview('pageviews',
  (response) => console.log('Personalization fetched'),
  (error) => console.error('Personalization failed')
)

Plugin Architecture

For advanced users who need custom plugin combinations:

import { 
  createSDK, 
  session, 
  record, 
  track, 
  clicks,
  utm,
  globalId 
} from 'td-web-sdk'

// Build custom SDK with only needed plugins
const sdk = createSDK({
  writeKey: 'your-key',
  database: 'your-db'
})
  .use(session())    // Identity & consent management
  .use(record())     // Core event submission  
  .use(track())      // Auto-tracked properties
  .use(clicks())     // Click tracking (optional)
  .use(utm())        // UTM collection (optional)
  .use(globalId())   // Global ID (optional)

// Same API as the full Treasure constructor
sdk.trackEvent('events', { custom: 'data' })

Automatic Data Collection

When using trackEvent() or trackPageview(), these properties are automatically included:

Property Description Example
td_version SDK version "1.0.0"
td_client_id Client UUID* "abc-123-def"
td_charset Page character set "utf-8"
td_language Browser language "en-us"
td_color Screen color depth "24-bit"
td_screen Screen resolution "1920x1080"
td_viewport Viewport size "1200x800"
td_title Page title "Home Page"
td_description Meta description "Welcome to..."
td_url Page URL "https://example.com/page"
td_user_agent User agent + SDK info "Mozilla/5.0...;WEBSDK/1.0.0"
td_platform Platform "MacIntel"
td_host Hostname "example.com"
td_path URL path "/products/123"
td_referrer Referrer URL "https://google.com"

Server-side properties (populated by Treasure Data):

Property Description Signed Mode Only
td_ip Request IP address

* Marked properties are considered PII and only sent in signed mode

Configuration Options

Core Configuration

const td = new Treasure({
  // Required
  writeKey: 'your-write-key',          // Get from Treasure Data console
  database: 'your-database',           // Target database name
  
  // Optional
  host: 'us01.records.in.treasuredata.com',  // API endpoint host
  development: false,                   // Enable development mode (no events sent)
  logging: true,                       // Enable console logging
  startInSignedMode: false,            // Default consent mode
  jsonpTimeout: 10000,                 // Request timeout (ms)
})

Personalization Configuration

When set, every trackEvent and trackPageview call fetches personalization and renders any in-browser messages instead of ingesting the event to your database. The personalization table is the table passed to the tracking call, and the request payload is the event data ($global + table defaults + track values + record).

const td = new Treasure({
  writeKey: 'key',
  database: 'db',
  personalization: {
    endpoint: 'personalization.example.com',  // Personalization API endpoint
    token: 'p13n_token_123',                   // Personalization API token
    database: 'recommendations_db'             // Optional; defaults to the main `database`
  }
})

Storage Configuration

const td = new Treasure({
  writeKey: 'key',
  database: 'db',
  storage: {
    name: '_td',                       // Cookie name
    expires: 63072000,                 // Expiry (seconds, 2 years default)
    domain: '.yourdomain.com',         // Cookie domain
    path: '/'                          // Cookie path
  }
})

// Disable cookie storage
const td = new Treasure({
  writeKey: 'key', 
  database: 'db',
  storage: 'none'
})

Server-Side Cookie Configuration

const td = new Treasure({
  writeKey: 'key',
  database: 'db',
  useServerSideCookie: true,
  sscDomain: 'yourdomain.com',         // Or function: () => window.location.hostname
  sscServer: 'ssc.yourdomain.com'      // Or function: (domain) => `ssc.${domain}`
})

API Reference

Constructor

new Treasure(config: TDConfig): Treasure

Parameters:

  • config (Object, required): Configuration object
    • writeKey (string, required): Write-only API key from Treasure Data console
    • database (string, required): Target database name
    • host (string, optional): API endpoint host. Default: 'us01.records.in.treasuredata.com'
    • development (boolean, optional): Development mode - logs events without sending. Default: false
    • logging (boolean, optional): Enable console logging. Default: true
    • startInSignedMode (boolean, optional): Start in signed mode. Default: false
    • jsonpTimeout (number, optional): Request timeout in milliseconds. Default: 10000
    • storage (Object|string, optional): Cookie storage configuration or 'none' to disable
    • useServerSideCookie (boolean, optional): Enable server-side cookie support. Default: false
    • personalization (Object, optional): Personalization config. When set, every trackEvent/trackPageview fetches personalization instead of ingesting the event
      • endpoint (string, required): Personalization API endpoint
      • token (string, required): Personalization API token
      • database (string, optional): Personalization database name. Defaults to the main database
      • The personalization table is the table passed to the tracking call (e.g. 'events', 'pageviews'), not configured here
      • The request payload is the event data ($global + table defaults + track values + the call's record), not configured here

Core Methods

addRecord(table, record, success?, error?)

Manual event submission without automatic tracking data.

Parameters:

  • table (string, required): Table name (3-255 chars, lowercase, numbers, underscore only)
  • record (Object, required): Event data object to send
  • success (Function, optional): Success callback (response: TrackResponse) => void
  • error (Function, optional): Error callback (error: TDError) => void

trackEvent(table?, record?, success?, error?)

Event tracking with automatic browser/session properties included. When personalization is configured on the constructor, fetches personalization instead of ingesting the event (see Behavior below).

Parameters:

  • table (string, optional): Table name. Default: 'events'
  • record (Object, optional): Additional event data. Default: {}
  • success (Function, optional): Success callback (response: TrackResponse) => void
  • error (Function, optional): Error callback (error: TDError) => void

Behavior:

  • When personalization is not configured: records the event with automatic properties via addRecord, invoking the success/error callbacks.
  • When personalization is configured (see Configuration Options): calls the personalization API instead of recording the event. The personalization table is table, and the request payload is the event data layered as $global → table defaults → automatic track values → record.
    • Personalization responses trigger in-browser message rendering
    • Personalization errors are logged
    • The success/error callbacks are not invoked on this path

trackPageview(table?, success?, error?, options?)

Page view tracking with automatic browser/session properties. Delegates to trackEvent, so it shares the same personalization behavior.

Parameters:

  • table (string, optional): Table name. Default: 'pageviews'
  • success (Function, optional): Success callback (response: TrackResponse) => void
  • error (Function, optional): Error callback (error: TDError) => void
  • options (Object, optional): Tracking options
    • payload (Object, optional): Additional event data to merge into the tracking record

Behavior:

  • Delegates to trackEvent with the resolved table name and options.payload as the record
  • When personalization is not configured on the constructor: records the pageview with automatic properties via addRecord
  • When personalization is configured: fetches personalization instead of ingesting (same XOR behavior as trackEvent). Personalization responses trigger in-browser message rendering and page personalization. Page personalization is suppressed while loaded in Personalization Studio

set(table, key, value) or set(table, object)

Set default properties for tables or globally.

Parameters:

  • table (string, required): Table name or '$global' for all tables
  • key (string, required): Property name (when using 3-parameter form)
  • value (JSONValue, required): Property value (when using 3-parameter form)
  • object (Object, required): Multiple properties object (when using 2-parameter form)

get(table?, key?)

Retrieve stored default properties.

Parameters:

  • table (string, optional): Table name. Default: '$global'
  • key (string, optional): Specific property name. If omitted, returns all properties for table

Returns: JSONValue - The property value or properties object

Identity & Privacy Methods

setSignedMode()

Enable signed mode - allows collection of PII (td_client_id, td_ip, td_global_id).

setAnonymousMode(keepIdentifier?)

Enable anonymous mode - blocks PII collection.

Parameters:

  • keepIdentifier (boolean, optional): Keep existing cookies/identifiers. Default: false

inSignedMode()

Check current privacy mode.

Returns: boolean - True if in signed mode, false if anonymous

blockEvents()

Block all event tracking. Events will not be sent or cached.

unblockEvents()

Resume event tracking.

areEventsBlocked()

Check if events are currently blocked.

Returns: boolean - True if events are blocked

resetUUID(storage?, clientId?)

Generate new client UUID and update cookie.

Parameters:

  • storage (Object, optional): Custom storage configuration
  • clientId (string, optional): Specific UUID to set. If omitted, generates random UUID

Plugin Methods

trackClicks(options?)

Enable automatic click tracking for buttons and links.

Parameters:

  • options (Object, optional): Click tracking configuration
    • tableName (string, optional): Table name. Default: 'clicks'
    • element (string|HTMLElement, optional): Target element or selector. Default: document

collectUTMParameters()

Extract UTM parameters from current URL.

Returns: Object - UTM parameters object (utm_source, utm_campaign, etc.)

getUTMParameters()

Get previously collected UTM parameters.

Returns: Object - Stored UTM parameters

fetchGlobalID(success?, error?, forceFetch?, options?)

Fetch Treasure Data Global ID for cross-device tracking.

Prerequisites: Must call setSignedMode() and set('$global', 'td_global_id', 'td_global_id') first.

Parameters:

  • success (Function, optional): Success callback (globalId: string | null) => void
  • error (Function, optional): Error callback (error: unknown) => void
  • forceFetch (boolean, optional): Skip cache and fetch fresh ID. Default: false
  • options (Object, optional): Cookie options
    • path (string, optional): Cookie path
    • domain (string, optional): Cookie domain
    • secure (boolean, optional): Secure flag
    • maxAge (number|string|Date, optional): Cookie expiry. Default: 6000
    • sameSite (string, optional): SameSite attribute ('None'|'Lax'|'Strict'). Default: 'None'

fetchServerCookie(success?, error?, forceFetch?)

Fetch server-side cookie for ITP compliance.

Prerequisites: Must enable with useServerSideCookie: true in config and call setSignedMode().

Parameters:

  • success (Function, optional): Success callback (serverSideId: string) => void
  • error (Function, optional): Error callback (error: string | Error) => void
  • forceFetch (boolean, optional): Skip cache and fetch fresh cookie. Default: false

fetchUserSegments(audienceToken, success?, error?) or fetchUserSegments(options, success?, error?)

Fetch user segments for personalization.

Parameters (Form 1):

  • audienceToken (string|string[], required): Audience token(s)
  • success (Function, optional): Success callback with segment data
  • error (Function, optional): Error callback

Parameters (Form 2):

  • options (Object, required): Segmentation options
    • audienceToken (string|string[], required): Audience token(s)
    • keys (Object, optional): Additional key-value data
  • success (Function, optional): Success callback with segment data
  • error (Function, optional): Error callback

fetchPersonalization(config, data?, success?, error?)

Fetch personalization data from CDP API.

Parameters:

  • config (Object, required): Personalization configuration
    • endpoint (string, required): API endpoint URL
    • database (string, required): Database name
    • table (string, required): Table name
    • token (string, required): API token
  • data (Object, optional): Additional request data
  • success (Function, optional): Success callback (response: Object) => void
  • error (Function, optional): Error callback (error: Error) => void

collectTags(options?)

Collect conversion tracking tags for ad platforms.

Parameters:

  • options (Object, optional): Collection options
    • table (string, optional): Table name for storing tags
    • success (Function, optional): Success callback (response: TrackResponse) => void
    • error (Function, optional): Error callback (error: TDError) => void

Examples

E-commerce Tracking

const td = new Treasure({ writeKey: 'key', database: 'ecommerce' })

// Product view
td.trackEvent('product_views', {
  product_id: 'SKU-123',
  category: 'electronics',
  price: 299.99,
  currency: 'USD'
})

// Purchase
td.trackEvent('purchases', {
  order_id: 'ORDER-456', 
  items: ['SKU-123', 'SKU-789'],
  total: 349.98,
  payment_method: 'credit_card'
})

// Set user context
td.set('$global', {
  user_id: '12345',
  customer_tier: 'gold',
  signup_date: '2024-01-15'
})

SaaS Application Analytics

const td = new Treasure({ writeKey: 'key', database: 'saas_analytics' })

// Feature usage
td.trackEvent('feature_usage', {
  feature: 'dashboard_export', 
  plan: 'pro',
  execution_time_ms: 1250
})

// User onboarding
td.trackEvent('onboarding_steps', {
  step: 'profile_completed',
  step_number: 3,
  time_to_complete_sec: 45
})

// Error tracking  
td.trackEvent('errors', {
  error_type: 'validation_failed',
  form: 'user_signup',
  field: 'email'
})

Content & Media Site

const td = new Treasure({ writeKey: 'key', database: 'content_analytics' })

// Article engagement
td.trackEvent('content_engagement', {
  article_id: 'post-123',
  engagement_type: 'scroll_75_percent',
  time_on_page_sec: 120,
  reading_speed_wpm: 200
})

// Video tracking
td.trackEvent('video_events', {
  video_id: 'vid-789',
  event: 'play', 
  position_sec: 0,
  duration_sec: 300
})

// Newsletter signup
td.trackEvent('conversions', {
  type: 'newsletter_signup',
  source: 'article_cta',
  article_category: 'technology'
})

Troubleshooting

Common Issues

Events not appearing in Treasure Data:

  • Check development: false in config
  • Verify writeKey and database are correct
  • Ensure events aren't blocked: td.areEventsBlocked()
  • Check browser console for error messages

TypeScript errors:

npm install --save-dev @types/node  # If using Node.js types

Global ID not working:

  • Must call td.setSignedMode() first
  • Must enable with td.set('$global', 'td_global_id', 'td_global_id')
  • Check HTTPS requirement for secure cookies

Server-side cookie fails:

  • Verify useServerSideCookie: true in config
  • Check sscDomain configuration
  • Ensure signed mode is enabled

Debug Mode

const td = new Treasure({
  writeKey: 'key',
  database: 'db', 
  development: true,  // Events logged, not sent
  logging: true       // Enable debug logs
})

Browser Support

  • Modern: Chrome 90+, Firefox 88+, Safari 14+, Edge 90+
  • Baseline: All browsers with ES2022 support
  • Polyfills: None required for target browsers

Security

  • All requests use HTTPS
  • Write-only API keys (no read access)
  • Optional PII collection controls
  • SameSite=None cookies for cross-site tracking
  • No sensitive data in localStorage

Development

Code Quality

This project uses automated code quality checks that run before each commit:

  • Type checking - TypeScript compilation validation
  • Linting - ESLint rules enforcement
  • Formatting - Prettier code formatting

Setting up pre-commit hooks

To enable automatic code quality checks on commit:

npm run hooks:install

This configures git to run type-check, linting, and formatting before each commit. If formatting changes are needed, the commit will be blocked and you'll need to review and stage the changes.

Manual code quality checks

You can also run these checks manually:

npm run type-check  # TypeScript compilation check
npm run lint        # ESLint linting
npm run lint:fix    # Auto-fix linting issues
npm run format      # Apply Prettier formatting
npm run format:check # Check formatting without applying changes

About

TreasureData Web SDK

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors