TD JavaScript SDK Quickstart

The Treasure Data JavaScript SDK (TD JS SDK) allows TD to store first-party cookies on your domain’s website and to track your website’s users across the other platforms and collect information. By using the TD JS SDK, you don’t have to install anything server-side to track website activities.

TD JS SDK Versions

The current versions of the TD JS SDK are

  • 4.1, hosted at https://cdn.treasuredata.com/sdk/4.1/td.min.js
  • 3.1, hosted at https://cdn.treasuredata.com/sdk/3.1/td.min.js
Earlier Versions of TD JS SDK

Treasure data recommends that you updgrade code using earlier version of the TD JS SDK to version 4.x or 3.x.

Prerequisites

  • Treasure Data Write-Only API Key
  • Database and table created on your TD account.

Setup

You can host a custom built version of the JavaScript SDK on your website or your preferred CDN. For the purpose of this quickstart we will be using a pre-built publically hosted version.

Installing the TD JS SDK with Script Snippet

Install td-js-sdk on your page by copying the appropriate JavaScript snippet below and pasting it into your page's <head> tag:

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

Installing the TD JS SDK with npm

Export the Treasure class using CommonJS.

Copy
Copied
npm install --save td-js-sdk

The entry point is lib/treasure.js. You can use this entry point with build tool such as Browserify or Webpack.

Copy
Copied
var Treasure = require('td-js-sdk')
note

This does not work with NodeJS. It is a browser-only solution.

Getting Your API Key

Warning

Treasure Data strongly recommends that you use a write-only API key for ingest and import operations and whenever using Treasure Data SDKs

Click here to see how to get a write-only API Key.

  1. Login to the Treasure Data Console and go to the API Key page .
  2. If you dont already have a write-only API key, then create one. From the top right, select Actions > Create API Key .
  3. Name the new API Key.
  4. From the Type drop-down menu, select Write-only .
  5. Select Save .
  6. Copy your new Write-Only API Key and use it authenticate the APIs in your project.

Initializing

The TD JS SDK creates a database and tables for each instance of the SDK, and it then sends data to those tables. After installing the TD JS SDK, initialize it with code similar to this:

Copy
Copied
  var foo = new Treasure({
    database: 'foo',
    writeKey: 'your_write_only_key'
  });

If you're an administrator, databases will automatically be created for you. Otherwise you'll need to ask an administrator to create the database and grant you import only or full access to the database. Without these permissions you will be unable to send events.

Sending Your First Event

After you have an object initialized, you can send events to Treasure Data. For a fully customized event record use the addRecord function. For example, you might use code similar to record an event:

Copy
Copied
// Configure an instance for your database
var company = new Treasure({...});

// Create a data object with the properties you want to send
var sale = {
  itemId: 101,
  saleId: 10,
  userId: 1
};

// Send it to the 'sales' table
company.addRecord('sales', sale);

Send as many events as you like. Each event will fire off asynchronously.

Tracking

The TD JS SDK provides a way to track page impressions and events, as well as client information.

Client ID and Storage

Each client requires a uuid. It may be set explicitly by setting clientId on the configuration object. Otherwise the TD JS SDK searches the cookies for a previously set UUID. If it is unable to find one, a UUID will be generated.

A cookie is set in order to track the client across sessions.

Page impressions

To track page impressions, use code similar to this:

Copy
Copied
/* insert javascript snippet */
var td = new Treasure({...});
td.trackPageview('pageviews');

This will send all the tracked information to the pageviews table.

Event tracking

In addition to tracking page views, you can track events. The syntax is similar to addRecord, but trackEvent gets all the tracked information. Here is an example of a td.trackEvent call:

Copy
Copied
var td = new Treasure({});

var buttonEvent1 = function () {
  td.trackEvent('button', {
    number: 1
  });

  // doButtonEvent(1);
};

var buttonEvent2 = function () {
  td.trackEvent('button', {
    number: 2
  });

  // doButtonEvent(2);
};

Tracked information

Every time a track functions is called, the following information is sent:

Event Name Description
td_version td-js-sdk's version
td_client_id Browser's cookie ID. In JS SDK 4.x this value is created by the client, and it is tracked by default.
td_charset character set
td_description description meta tag
td_language browser language
td_color screen color depth
td_screen screen resolution
td_viewport viewport size
td_title document title
td_url document url
td_user_agent Browser user agent. This is comprised of a userAgent variable (obtained through the navigator.userAgent function), and a sdkUserAgent variable that contains the JSSDK version number.
td_platform browser platform
td_host document host
td_path document pathname
td_referrer document referrer
td_ip request IP (server). This is a personally identifiable column, and will be affected by whether or not the user is in Signed or Anonymous Mode. In JS SDK 4.x this value is generated by the server, and it is tracked by default.
td_browser Client browser (server). JS SDK 4.x does not populate this field; to obtain this value use the the Hive or Presto function TD_PARSE_USER_AGENT.
td_browser_version Client browser version (server). JS SDK 4.x does not populate this field; to obtain this value use the the Hive or Presto function TD_PARSE_USER_AGENT.
td_os Client operating system (server). JS SDK 4.x does not populate this field; to obtain this value use the the Hive or Presto function TD_PARSE_USER_AGENT.
td_os_version Client operating system version (server). JS SDK 4.x does not populate this field; to obtain this value use the the Hive or Presto function TD_PARSE_USER_AGENT.

Certain values cannot be obtained from the browser. For these values, the SDK sends matching keys and values, and the server replaces the values upon receipt. For example: {"td_ip": "td_ip"} is sent by the browser, and the server will update it to something like {"td_ip": "1.2.3.4"}

All server values except td_ip are found by parsing the user-agent string. This is done server-side to ensure that it can be kept up to date.

Default values

You can set default values on a table by using Treasure#set. you can set default values on all tables by passing $global as the table name.

Using Treasure#get you can view all global properties by passing the table name $global.

When a record is sent, an empty record object is created and properties are applied to it in the following order:

  1. $global properties are applied to record object
  2. Table properties are applied to record object, overwriting $global properties
  3. Record properties passed to addRecord function are applied to record object, overwriting table properties

Collecting Third-Party Conversion Tags

Third-party tags, such as a Meta Click ID, could be embedded in your website as cookies or request parameters when the user lands on your website via advertising content. In the JS SDK 4.1 or above, you can collect those tags using collectTags.

Copy
Copied
td.collectTags(
  {
    vendors: ['google_ads', 'google_mp', 'meta', 'x'],
    cookies: ['_cookie_a', '_cookie_b'],
    params: ['param_a', 'param_b']
  }, 
  {
    gclPrefix: '_gcl2'
  }
)

The list of supported vendor names can be found in the Third-party Conversion Tags Collection with JS-SDK.

Data Privacy

Treasure Data's SDK enables compliance with many common requirements of the EU's GDPR laws. Several methods have been enabled to help you comply with newer and more stringent data privacy policies:

  • blockEvents / unblockEvents - non-argument methods to shut down or re-enable all sending of events to Treasure Data. If specified, no messages will be sent, no calls will be cached. Default is for events to be unblocked. See documentation for these methods:
  • setSignedMode - non-argument method to enter "Signed Mode", where some PII may be collected automatically by the SDK. If specified, the data sent to Treasure Data will include td_ip , td_client_id , and td_global_id . See documentation for setSignedMode .
  • setAnonymousMode - non-argument method to enter "Anonymous Mode", where PII will not be collected automatically by the SDK. If specified, this will specifically omit td_ip , td_client_id , and td_global_id from data being sent. This is the default behavior. See documentation for setAnonymousMode .
  • resetUUID - method to reset the td_client_id value. This will overwrite the original value stored on the user's cookie, and will likely appear in your data as a brand-new user. It's possible to specify a client ID while resetting, as well as custom expiration times by passing in appropriate values. See documentation for resetUUID .
  • config.startInSignedMode . This configuration option tells the SDK that, if no express decision has been made on whether the user wants to be in Signed or Anonymous modes, it should default into Signed Mode. The default behavior is to default the user into Anonymous Mode.

Examples

Suppose a new user accesses your site, and you need to know if they have agreed to cookie tracking for marketing purposes. You contract with a Consent Management Vendor to maintain this information, and want to set appropriate values once you know their consent information.

Copy
Copied
var foo = new Treasure({
  database: 'foo',
  writeKey: 'your_write_only_key'
});
td.trackClicks()

var successConsentCallback = function (consented) {
  if (consented) {
    td.setSignedMode()
  } else {
    td.setAnonymousMode()
  }
}

var failureConsentCallback = function () {
  // error occurred, consent unknown
  td.setAnonymousMode()
}

ConsentManagementVendor.getConsent(userId, successConsentCallback, failureConsentCallback)

In this scenario, the Consent Management Vendor returns a true or false value in the callback based on whether or not the user associated with the userId has consented to their PII being used for marketing purposes. Non-PII data may still be collected.

Now suppose your Consent Management Vendor provides strings based on the consent level: MARKETING, NON-MARKETING, REFUSED, for "Consented to PII being used for marketing purposes", "Consented to data being collected for non-marketing purposes", and "Refused all data collection". There's only a minor change to make in the successConsentCallback:

Copy
Copied
var successConsentCallback = function (consented) {
  if (consented === 'MARKETING') {
    td.unblockEvents()
    td.setSignedMode()
  } else if (consented === 'NON-MARKETING') {
    td.unblockEvents()
    td.setAnonymousMode()
  } else if (consented === 'REFUSED') {
    td.blockEvents()
  }
}

In this way, when emerging from Signed or Anonymous mode, you can be sure you'll actually be collecting data into Treasure Data. If the customer has refused all tracking, their events are blocked, and this status will be persisted across page refreshes.

SameSite Cookies

In recent releases of Chrome and Firefox, they began enforcing a new secure-by-default cookie classification system, treating cookies that have no declared SameSite value as SameSite=Lax cookies. Only cookies set as SameSite=None; Secure will be available in third-party contexts, provided they are being accessed from secure connections.

For JS SDK versions earlier than 2.4.2, this affected the td_client_id and td_global_id cookies as they were not set as secured cookies.

For JS SDK version 2.4.2 and above, TreasureData JS SDK uses SameSite=None; Secure cookies as default to adapt the new cookie enforcement.

For more information see

Streaming Ingestion

The way the JS SDK handles data ingestion is dependent on the version of the SDK you are using.

JS SDK Version Ingestion Method
4.1 Only the new Mobile/Javascript REST API (records.in.treasuredata.com).
3.1.x Either
  • Legacy Mobile/Javascript SDK endpoint (in.treasuredata.com)
  • New Mobile/Javascript REST API (records.in.treasuredata.com)
The functionality is determined using the parameter useNewJavaScriptEndpoint.
3.1.0 and earlier (Deprecated) Only the Legacy Mobile/Javascript SDK endpoint only.

Configuration

The useNewJavaScriptEndpoint takes a true or false value. When you enable this option, you need to change the host configuration as well, so that it will point to the new endpoint. This new feature does not impact the server side cookie and the personalization features of the SDK.

note

The records.in endpoint has the following limitations:

  • 1 to 500 events.
  • Maximum 1000kiB per event.
  • Maximum 5MiB for all events.

The host configuration will have the following values, depending on which environment you want to ingest data.

Region Ingestion Endpoint
US us01.records.in.treasuredata.com
Tokyo ap01.records.in.treasuredata.com
Europe eu01.records.in.treasuredata.com
Korea ap02.records.in.treasuredata.com

Internal Only

Console Ingestion Endpoint
Development us01-development.records.in.treasuredata.com
Staging us01-staging.records.in.treasuredata.com

JS SDK 4.1 example

Copy
Copied
  var foo = new Treasure({
    database: 'foo',
    writeKey: 'your_write_only_key',
    host: 'us01.records.in.treasuredata.com'
  });

When you opt-out of this feature by either setting the useNewJavaScriptEndpoint to false or not setting it, make sure that you update the host to the old configuration.

JS SDK 3.1 example

Copy
Copied
  var foo = new Treasure({
    database: 'foo',
    writeKey: 'your_write_only_key',
    useNewJavaScriptEndpoint: true,
    host: 'us01.records.in.treasuredata.com'
  });

When you opt-out of this feature by either setting the useNewJavaScriptEndpoint to false or not setting it, make sure that you update the host to the old configuration.

Limitations and Changed behavior

The following changes and limitations were introduced in JS SDK 4.1:

  • Using Real-time segmentation requires routing enablement from the backend. Contact Technical Support or your Customer Success representative to enable routing. Provide account , database , and table to enable routing.

  • td_browser , td_browser_version , td_os , and td_os_version are not tracked by JS SDK 4.x . To obtain this value use td_user_agent with the Hive or Presto function TD_PARSE_USER_AGENT .

  • The records.in endpoint has the following limitations:
    • 1 to 500 events.
    • Maximum 1000kiB per event.
    • Maximum 5MiB for all events.

Further Reading

Here are some additional resources for the JS SDK: