Skip to content
Last updated

TD Web SDK Integration

This guide explains how to install the TD Web SDK (td-web-sdk) on your website and configure it for In-Browser Messaging. Complete this setup before creating campaigns in Engage Studio.

Who should read this

This page is for web developers who are adding the SDK to a website. Marketers who are creating campaigns can skip to Create a Popup Campaign or Create an Inline Campaign once setup is complete.

Step 1 — Install the SDK

Choose the installation method that matches your project.

Add the async loader snippet to the <head> of every page. This is the fastest way to get started and works with any tech stack.

<head>
  <!-- TD Web SDK async loader -->
  <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","trackEvent","trackPageview","trackClicks","addRecord","setSignedMode","setAnonymousMode","blockEvents","unblockEvents","fetchGlobalID","fetchServerCookie","fetchUserSegments","fetchPersonalization","resetUUID","collectTags","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://cdn.treasuredata.com/sdk/web/1.0/td-sdk.min.js";var i=document.getElementsByTagName("script")[0];i.parentNode.insertBefore(n,i)}}("Treasure",this);
  </script>
</head>
CDN versioning

The path /sdk/web/1.0/ pins to the minor version. Patch releases are automatically reflected without requiring a snippet update.

Step 2 — Initialize the SDK

Create one Treasure instance and keep a reference to it. Call initialization as early as possible — before any trackEvent calls.

const td = new Treasure({
  writeKey: 'YOUR_WRITE_KEY',   // Write-only API key from your TD account
  database: 'YOUR_DATABASE',    // Target database name
  host: 'YOUR_REGION_HOST',     // See region list below
})

Enable In-Browser Messaging (Personalization)

To receive popup or inline messages from Engage Studio, add the personalization option. When configured, trackEvent calls are routed through the RT Personalization API instead of the standard ingest endpoint — the SDK fetches the campaign payload and renders the message automatically.

const td = new Treasure({
  writeKey: 'YOUR_WRITE_KEY',
  database: 'YOUR_DATABASE',
  host: 'YOUR_REGION_HOST',
  personalization: {
    endpoint: 'YOUR_P13N_ENDPOINT',  // Region-dependent. Ask your CSM.
    token: 'YOUR_WP13N_TOKEN',       // WP13n-Token from Audience Studio
  },
})
Personalization replaces ingest

When personalization is configured, events are not written to your TD database — they are sent to the RT Personalization API instead. If you need both ingest and personalization, contact your Customer Success Manager for guidance on the dual-path pattern.

Configuration Reference

Option Required Description
writeKeyWrite-only API key. Found in your TD account settings.
databaseTarget database name where events are stored.

host

Data ingestion endpoint. Select the value for your region:

RegionHost
USus01.records.in.treasuredata.com
Tokyoap01.records.in.treasuredata.com
AP02ap02.records.in.treasuredata.com
EU01eu01.records.in.treasuredata.com
personalization.endpoint✅ (if using In-Browser Messaging)RT Personalization API endpoint. Region-dependent.
personalization.token✅ (if using In-Browser Messaging)WP13n-Token from the Personalization settings in Audience Studio.
startInSignedModeSet to true to collect PII (client ID, IP) from the first event. Default: false (anonymous mode).
loggingEnable SDK console logging for debugging. Default: true in development.

Step 3 — Track Page Views

Fire a page view event on every page load or SPA route change using trackEvent with event_name: 'page_view'. This is required for RT Personalization to evaluate entry criteria and deliver messages.

Call trackEvent on every page load. Because the page reloads on each navigation, one call per page is sufficient.

<script>
  // After SDK initialization
  td.trackEvent('events', { event_name: 'page_view' })
</script>

Step 4 — Set User Identity

The SDK provides two mechanisms for anonymous identity. Server-Side Cookie (td_ssc_id) is recommended because it is issued by your own server and is not subject to browser ITP restrictions that limit first-party cookies to 7 days.

td_ssc_id is a cookie set by your server, not the browser. It persists reliably across Safari ITP and iOS environments and is the preferred identifier for In-Browser Messaging.

Infrastructure required first: A small SSC server endpoint must be deployed on your domain (e.g., ssc.yourdomain.com). Contact your Customer Success Manager or implementation team for the SSC server setup guide.

Once the SSC infrastructure is in place:

const td = new Treasure({
  writeKey: 'YOUR_WRITE_KEY',
  database: 'YOUR_DATABASE',
  host: 'YOUR_REGION_HOST',
  useServerSideCookie: true,
  sscDomain: 'yourdomain.com',   // Your root domain
  personalization: {
    endpoint: 'YOUR_P13N_ENDPOINT',
    token: 'YOUR_WP13N_TOKEN',
  },
})

// Enable signed mode, then fetch the server-side cookie
td.setSignedMode()
td.fetchServerCookie(
  (sscId) => console.log('SSC ID:', sscId),
  (error) => console.error('SSC fetch failed:', error)
)

After fetchServerCookie succeeds, the td_ssc_id is automatically included in all subsequent events.

SSC prerequisites

fetchServerCookie requires:

  1. useServerSideCookie: true in the SDK config
  2. setSignedMode() called before fetchServerCookie()
  3. The SSC server endpoint deployed and accessible on your domain

If SSC infrastructure is not yet available, the SDK falls back to td_client_id — a first-party cookie set by the browser. It works without any server infrastructure, but is subject to ITP restrictions (7-day cap on Safari/iOS).

// No extra config needed — td_client_id is managed automatically
const td = new Treasure({
  writeKey: 'YOUR_WRITE_KEY',
  database: 'YOUR_DATABASE',
  host: 'YOUR_REGION_HOST',
  personalization: {
    endpoint: 'YOUR_P13N_ENDPOINT',
    token: 'YOUR_WP13N_TOKEN',
  },
})
Identifier Set by ITP / Safari Infrastructure Recommendation
td_ssc_idYour server✅ Not affectedSSC server requiredRecommended
td_client_idBrowser (JS)⚠️ 7-day capNoneFallback only

Setting Authenticated User ID

After a user logs in, pass your internal user ID so events can be linked across devices and channels regardless of which cookie is in use.

// After login / session restore
td.set('$global', 'td_user_id', 'YOUR_INTERNAL_USER_ID')

// From this point, all events include td_user_id
td.trackEvent('events', { event_name: 'page_view' })
Identity design

Use a stable, non-PII internal ID (account ID, CRM ID) — not email or phone number. Only set td_user_id after the user is authenticated.

Anonymous vs Signed Mode

By default the SDK runs in anonymous mode — identifiers and IP address are not sent. Enable signed mode when the user has consented to tracking.

// User has consented — enable PII collection (required for SSC)
td.setSignedMode()

// User has withdrawn consent
td.setAnonymousMode()

// Block all events (e.g., cookie banner rejection)
td.blockEvents()
td.unblockEvents() // Resume

Step 5 — Verify the Setup

Open your browser's DevTools → Network tab and filter for requests to your host or personalization.endpoint domain. After calling trackEvent, you should see:

  • Without personalization: a POST request to the ingest endpoint with the event payload.
  • With personalization: a POST request to the p13n endpoint; the response contains the offers object with any active campaign payloads.

You can also check the Console tab — the SDK logs [td-debug] messages showing the request URL and payload.

User Identity and Privacy

The anonymous-to-identified transition

User visits (no login)
  └─ td_ssc_id issued by your server (recommended)
     OR td_client_id set by browser (fallback)
  └─ Events sent anonymously

User logs in
  └─ td.set('$global', 'td_user_id', 'user_12345')
  └─ All subsequent events include both cookie ID + td_user_id
  └─ RT 2.0 ID stitching links the anonymous history to the user

Automatically collected properties

The SDK attaches these fields to every event automatically — no implementation required:

Property Description PII?
td_ssc_idServer-side cookie identifier (recommended — not ITP-affected)Yes (signed mode only)
td_client_idFirst-party browser cookie identifier (fallback — ITP 7-day cap on Safari)Yes (signed mode only)
td_session_idPer-session UUID (future SDK versions)No
td_urlCurrent page URLPotentially
td_pathURL path (e.g., /product/123)No
td_hostHostnameNo
td_referrerReferring URLPotentially
td_titlePage titleNo
td_viewportBrowser window size (WxH)No
td_screenScreen resolution (WxH)No
td_languageBrowser languageNo
td_user_agentBrowser User-Agent stringPotentially
td_versionSDK versionNo

Next Steps