# 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.4, hosted at `https://cdn.treasuredata.com/sdk/4.4/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 - Basic knowledge of JavaScript and HTML - Basic knowledge of Treasure Data - Treasure Data Write-Only API Key - Database and table created on your TD account - The [site and endpoint specific to your region](https://api-docs.treasuredata.com/en/overview/aboutendpoints/) ## Limitations IP whitelist is not applied to any import from the JavaScript SDK. Web browsers frequently specify invalid timestamps (such as 1970/01/01). For this reason, logs that have a timestamp older than 7 days, or are 3 days ahead of the current date are ignored. # 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 `
` tag: ```html version 4.4 ``` ```html version 3.1 ``` ## Installing the TD JS SDK with npm Export the `Treasure` class using CommonJS. ```bash 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. ```javascript var Treasure = require('td-js-sdk') ``` This does not work with NodeJS. It is a browser-only solution. ## Getting Your API Key `YOUR_API_KEY` should be your actual apikey string. You can retrieve your API key from your profiles in TD Console. Using a [write-only API key](/products/my-settings/getting-your-api-keys) is recommended. ## 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: ```javascript // Configure an instance for your database var td = new Treasure({ host: 'YOUR_REGION.records.in.treasuredata.com', writeKey: 'YOUR_WRITE_ONLY_APIKEY_IS_HERE', database: 'DATABASE_NAME' }); ``` 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. Replace `YOUR_REGION` with your regional endpoint (e.g., `us01`, `eu01`, `ap01`). See the [Streaming Ingestion](#streaming-ingestion) section below for more details on regional endpoints. ## 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: ```javascript // 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: ```javascript /* insert javascript snippet */ var td = new Treasure({...}); // Enable cross-domain tracking td.set('$global', 'td_global_id', 'td_global_id'); // Track pageview information to 'pageviews' table td.trackPageview('pageviews'); ``` This will send all the tracked information to the `pageviews` table. ### Setting Custom Parameters If you want to set custom parameters, use the `td.set()` function: ```javascript // track pageview information to 'pageviews' table td.set('pageviews', {foo: 'foo', bar: 'bar'}); td.trackPageview('pageviews'); ``` ## Event tracking In addition to tracking page views, you can track custom events using the `trackEvent()` function. The syntax is similar to `addRecord`, but `trackEvent` gets all the tracked information. In the following example, `button` is the name of table where events get logged. You can pass additional information and context to the event as an argument. ```javascript var td = new Treasure({}); var buttonEvent1 = function () { td.trackEvent('button', { number: 1 }); // doButtonEvent(1); }; var buttonEvent2 = function () { td.trackEvent('button', { number: 2 }); // doButtonEvent(2); }; ``` Each event fires off asynchronously. ## Enabling Tracking by Individual (Data Privacy) To comply with data privacy regulations in various domains, and specifically GDPR, the Treasure Data Javascript SDK operates in **anonymous mode** by default, which means that it does not collect certain event metadata that is personally identifiable. Specifically, by default the following information is not collected in anonymous mode: * `td_ip` - request IP (added at the server-side) * `td_client_id` - client's uuid (1st party cookie - see [Anonymous IDs](/products/customer-data-platform/integration-hub/streaming/td-javascript-sdk/anonymous-visitor-ids-with-javascript-sdk)) * `td_global_id` - client's uuid (3rd party cookie - see [Anonymous IDs](/products/customer-data-platform/integration-hub/streaming/td-javascript-sdk/anonymous-visitor-ids-with-javascript-sdk)) `td_client_id` and `td_global_id` are needed if you want to track individual users and analyze their data within and across user sessions, associate the tracked behavior with a real-world individual, and more. You must review your data collection policy with your company's data privacy officer and legal counsel to determine whether you collect personal information. If you decide to enable tracking of individuals, we recommend that you integrate with a consent management system to track individual user opt-ins for tracking. When you have determined the user consent, you can enable **signed mode** of the JS SDK to capture these attributes with your events: ```javascript td.setSignedMode() ``` ## 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. It is considered Personally Identifiable Information (PII), and it is only tracked if `inSignedMode()` is TRUE. | | `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 information is only populated when `td_global_id` is enabled using `td.set('$global', 'td_global_id', 'td_global_id')` and is in signed mode. It is considered Personally Identifiable Information (PII), and it is only tracked if `inSignedMode()` is TRUE. | | `td_browser` | Client browser (server). JS SDK 4.x does not populate this field; to obtain this value use the the Hive or Trino(Presto) function [TD_PARSE_USER_AGENT](https://api-docs.treasuredata.com/en/tools/hive/td_hive_function_reference/#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 Trino(Presto) function [TD_PARSE_USER_AGENT](https://api-docs.treasuredata.com/en/tools/hive/td_hive_function_reference/#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 Trino(Presto) function [TD_PARSE_USER_AGENT](https://api-docs.treasuredata.com/en/tools/hive/td_hive_function_reference/#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 Trino(Presto) function [TD_PARSE_USER_AGENT](https://api-docs.treasuredata.com/en/tools/hive/td_hive_function_reference/#td_parse_user_agent). | 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`. ```javascript 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](https://docs.treasuredata.com/products/customer-data-platform/integration-hub/streaming/td-javascript-sdk/third-party-conversion-tags-collecting-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: - [blockEvents](/products/customer-data-platform/integration-hub/streaming/td-javascript-sdk/api#treasureblockevents) - [unblockEvents](/products/customer-data-platform/integration-hub/streaming/td-javascript-sdk/api#treasureunblockevents) - [areEventsBlocked](/products/customer-data-platform/integration-hub/streaming/td-javascript-sdk/api#treasureareeventsblocked) - `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](/products/customer-data-platform/integration-hub/streaming/td-javascript-sdk/api#treasuresetsignedmode). - `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](/products/customer-data-platform/integration-hub/streaming/td-javascript-sdk/api#treasuresetanonymousmode). - `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](/products/customer-data-platform/integration-hub/streaming/td-javascript-sdk/api#treasureresetuuid). - `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. ```javascript 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`: ```js 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 - **Firefox**: [Changes to SameSite Cookie Behavior](https://hacks.mozilla.org/2020/08/changes-to-samesite-cookie-behavior/) - **Chrome**: [SameSite Cookie Changes in February 2020: What You Need to Know](https://blog.chromium.org/2020/02/samesite-cookie-changes-in-february.html) # 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 and above | 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. The `records.in` endpoint has the following limitations: - 1 to 500 records. - 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 | **JS SDK 4.4 example** ```js 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** ```js 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 and above: - 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 Trino(Presto) function [TD_PARSE_USER_AGENT](https://api-docs.treasuredata.com/en/tools/hive/td_hive_function_reference/#td_parse_user_agent). - The `records.in` endpoint has the following limitations: - 1 to 500 records. - Maximum 1000kiB per event. - Maximum 5MiB for all events. # Realtime Personalization 2.0 Introducing a [new API](/products/customer-data-platform/integration-hub/streaming/td-javascript-sdk/api#fetchpersonalizationconfig-data-successcallback-errorcallback), `fetchPersonalization`, allows customers to fetch personalization data to serve personalized content to consumers. ### Endpoints - us01.p13n.in.treasuredata.com - eu01.p13n.in.treasuredata.com - ap01.p13n.in.treasuredata.com - ap03.p13n.in.treasuredata.com # UTM Parameters tracking This feature is supported in the td-js-sdk v4.4.0 Allow marketers to track performance across email and landing pages to measure engagement, conversion, and revenue attribution effectively. The following UTM parameters will be tracked automatically: - *utm_id* - *utm_medium* - *utm_source_platform* - *utm_source* - *utm_campaign* - *utm_marketing_tactic* ### How does it work? When a webpage is loaded with the UTM parameters, our JS SDK will collect these parameters automatically and add them to the $global table, as the result the parameters will be sent along with tracking requests, such as pageviews, tracking event… # REST API Direct Usage JavaScript SDK uses our [REST API endpoint](https://api-docs.treasuredata.com/en/overview/aboutendpoints/) to import the data and it might take a few minutes to reflect the import in the database because of server-side buffering. * X-TD-Data-Type: k—Event collector handles several data types. 'k' is one of them. It can handle multiple records. **Single Record** ```bash $ curl -X POST -H 'Content-Type: application/json' -H 'X-TD-Write-Key: your_write_apikey' \ --data-binary '{"name":"komamitsu", "num":1234}' \ https://your_region.treasuredata.com/js/v3/event/your_db/your_table ``` **Multiple Records** ```bash $ curl -X POST -H 'Content-Type: application/json' -H 'X-TD-Write-Key: your_write_apikey' \ -H 'X-TD-Data-Type: k' \ --data-binary '{"your_db.your_table":[{"time":1403147720, "name":"komamitsu", "age":41},{"time":1403147721, "name":"kzk", "age":29}]}' \ https://your_region.treasuredata.com/js/v3/event ``` When you try the preceding example, change the time value to the current UNIX time value. Timestamps that are older than 7 days, or are 3 days ahead of the current date are ignored. # Further Reading Here are some additional resources for the JS SDK: - [td-js-sdk README on GitHub repo](https://github.com/treasure-data/td-js-sdk#td-js-sdk) - [TD JavaScript API Reference](/products/customer-data-platform/integration-hub/streaming/td-javascript-sdk/api#td-js-sdk-apis)