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.
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.
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>The path /sdk/web/1.0/ pins to the minor version. Patch releases are automatically reflected without requiring a snippet update.
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
})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
},
})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.
| Option | Required | Description | ||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
writeKey | ✅ | Write-only API key. Found in your TD account settings. | ||||||||||
database | ✅ | Target database name where events are stored. | ||||||||||
| — | Data ingestion endpoint. Select the value for your region:
| ||||||||||
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. | ||||||||||
startInSignedMode | — | Set to true to collect PII (client ID, IP) from the first event. Default: false (anonymous mode). | ||||||||||
logging | — | Enable SDK console logging for debugging. Default: true in development. |
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>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.
fetchServerCookie requires:
useServerSideCookie: truein the SDK configsetSignedMode()called beforefetchServerCookie()- 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_id | Your server | ✅ Not affected | SSC server required | Recommended |
td_client_id | Browser (JS) | ⚠️ 7-day cap | None | Fallback only |
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' })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.
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() // ResumeOpen 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
offersobject 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 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 userThe SDK attaches these fields to every event automatically — no implementation required:
| Property | Description | PII? |
|---|---|---|
td_ssc_id | Server-side cookie identifier (recommended — not ITP-affected) | Yes (signed mode only) |
td_client_id | First-party browser cookie identifier (fallback — ITP 7-day cap on Safari) | Yes (signed mode only) |
td_session_id | Per-session UUID (future SDK versions) | No |
td_url | Current page URL | Potentially |
td_path | URL path (e.g., /product/123) | No |
td_host | Hostname | No |
td_referrer | Referring URL | Potentially |
td_title | Page title | No |
td_viewport | Browser window size (WxH) | No |
td_screen | Screen resolution (WxH) | No |
td_language | Browser language | No |
td_user_agent | Browser User-Agent string | Potentially |
td_version | SDK version | No |
- Define Business Events — set up
view_item,add_to_cart,purchase, and other custom events - Create a Popup Campaign
- Create an Inline Campaign