How can we help?

✪ Embedded JavaScript Listener v2

Overview

Using the available JavaScript methods you can:

Each browser is assigned a unique browser ID (BID). Multiple BID's can be associated with a contact, depending on their browsing activity. This makes it possible to identify a user across different browsers and domains.

  • If a contact arrives on your site from a tracked link, cookies will be set to identify the contact.
  • If the user has not arrived from a tracked link, the user can be added or updated using the crdl('contact') method.
  • If there is no referring message or known contact identifier available, an anonymous BID will be assigned to the session user.

All activity (orders, cart, events) will be tracked for 30 days and attributed to the anonymous BID. In the event that a contact identifier becomes available for the anonymous user, activity thereafter will be tracked and attributed to the known contact, and previously generated activity from their anonymous session will be copied into their contact record.

Event activity belonging to anonymous users cannot be viewed in the Cordial platform until the user's record is created through identification.

Due to data privacy compliance requirements (e.g. GDPR and CCPA), certain functionality of adding and editing contacts via JavaScript requires explicit consent and additional setup. Please contact your Client Success Manager or submit a support request for more info.

The manner in which track script stores and uses cookies may change from time to time without notice to accommodate changes to Cordial products and servicesand in response to new technologies and industry practices.

Installation

If you log in to your Cordial account using the address https://admin.cordial.io, you will use the following code for your staging site. This snippet should be included before the closing body tag of the site or site template, with the placeholder account key value updated for your account:

<script>
(function(C,O,R,D,I,A,L){
  C.CordialObject=I,C[I]=C[I]||function(){(C[I].q=C[I].q||[]).push(arguments)};
  C[I].l=1*new Date,C[I].q=[],A=O.createElement(R);
  L=O.getElementsByTagName(R)[0],A.async=1,A.src=D,L.parentNode.insertBefore(A,L);
})(window, document, "script", "//track.cordial.io/track.v2.js", "crdl");

crdl("connect", "YOUR_ACCOUNT_KEY_HERE", { 
    trackUrl: "//track.cordial.io",
    connectUrl: "//track.cordial.io",
    cookieDomain: "cordial.io",
    cookieLife: 365
});
</script>

In production, your code snippet should look more like this (using your vanity domain and Cordial account key):

<script>
(function(C,O,R,D,I,A,L){
  C.CordialObject=I,C[I]=C[I]||function(){(C[I].q=C[I].q||[]).push(arguments)};
  C[I].l=1*new Date,C[I].q=[],A=O.createElement(R);
  L=O.getElementsByTagName(R)[0],A.async=1,A.src=D,L.parentNode.insertBefore(A,L);
})(window, document, "script", "//d.email.example.com/track.v2.js", "crdl");

crdl("connect", "YOUR_ACCOUNT_KEY_HERE", { 
    trackUrl: "//se.email.example.com",
    connectUrl: "//d.email.example.com",
    cookieDomain: "email.example.com",
    cookieLife: 365
});
</script>

US-West-2

If you log in to your Cordial account using the address https://usw2.admin.cordial.io, use the following code for your staging site. This snippet should be included before the closing body tag of the site or site template, with the placeholder account key value updated for your account:

<script>
(function(C,O,R,D,I,A,L){
  C.CordialObject=I,C[I]=C[I]||function(){(C[I].q=C[I].q||[]).push(arguments)};
  C[I].l=1*new Date,C[I].q=[],A=O.createElement(R);
  L=O.getElementsByTagName(R)[0],A.async=1,A.src=D,L.parentNode.insertBefore(A,L);
})(window, document, "script", "//track.usw2.cordial.com/track.v2.js", "crdl");

crdl("connect", "YOUR_ACCOUNT_KEY_HERE", {
    trackUrl: "//track-ehs-svc.usw2.cordial.com",
    connectUrl: "//track.usw2.cordial.com",
    cookieDomain: "cordial.com",
    cookieLife: 365
});
</script>

In production, your code snippet should look more like this (using your vanity domain and Cordial account key):

<script>
(function(C,O,R,D,I,A,L){
  C.CordialObject=I,C[I]=C[I]||function(){(C[I].q=C[I].q||[]).push(arguments)};
  C[I].l=1*new Date,C[I].q=[],A=O.createElement(R);
  L=O.getElementsByTagName(R)[0],A.async=1,A.src=D,L.parentNode.insertBefore(A,L);
})(window, document, "script", "//d.email.example.com/track.v2.js", "crdl");

crdl("connect", "YOUR_ACCOUNT_KEY_HERE", { 
    trackUrl: "//se.email.example.com",
    connectUrl: "//d.email.example.com",
    cookieDomain: "email.example.com",
    cookieLife: 365
});
</script>

Please reach out to your CSM if you have questions regarding which set of code snippets applies to your account, or if you're unsure what code snippet to use for your staging environment vs. production environment.

Set the accountKey

Replace the YOUR_ACCOUNT_KEY_HERE with your Cordial account key. In the UI, navigate to Settings > Account Settings > Account Info to find your Cordial account key.

Set the cookieDomain

In most instances, contacts will be identified upon visiting your base domain. In order to remain identified when moving from the base domain to a subdomain, such as shop.yourbasedomain.com, it is necessary to store cookies at the base domain level. This will allow cookies to be shared across subdomains branching from the base domain.

Ensure your base domain is entered as a root domain, without the www. subdomain. Adding www. before your base domain will cause it to be treated as a subdomain, and cookies stored under this subdomain will not be accessible to other subdomains such as shop.yourbasedomain.com.

Set the configuration

crdl('connect', YOUR_ACCOUNT_KEY_HERE, {config});

You can override the following default configurations.

Parameter Type Description Default
trackUrl string The Cordial endpoint that track calls will be sent to (only special situations may require a change, e.g. a custom domain). track.cordial.io
connectUrl string The endpoint for connecting with Cordial cookies (only special situations may require a change, e.g. a custom domain). track.cordial.io
cookieDomain string Sets which domain cookie will get stored. (only special situations may require a change, e.g. a custom domain). cordial.io
cookieLife integer Expiration of cookie in days, default is 365 days. 365
crdl('connect', 'cordial', { 
    trackUrl: "//track.cordial.io" ,
    connectUrl: "//track.cordial.io" ,
    cookieDomain: "cordial.io",
    cookieLife: 365,
});

Cookie expiration has no bearing on the 30 day mcID expiration period used for revenue attribution. See the revenue attribution article to learn more.

Cookie expiration is reset to the cookieLife value when the web page containing the JavasScript configuration snipped is refreshed.

crdl(contact) - Add and update a contact

You can call crdl(contact) to add or update a contact record.

crdl('contact', auth_data, contact_data)

You can pass an object with authentication data such as an email address (or any other valid contact identifier key/value pair), subscribe status, attribute values, and list associations for a new or existing contact.

Some form of authentication data is required for creating or updating contact records.

The crdl(contact) method can be used in a similar manner to cordial.identify(), which is a JavaScript Listener v1 method. Simply use this format: crdl('contact', {email: 'name@example.com'}, {}). The contact_data placeholder must be included but can be empty. For contact authentication, you can use other contact identifier key/value pairs supported in your account such as cID: '58d2fc99ac0c8117814d4e78', or customKey: 'cust-id-123'.

If available contact authentication data does not match the existing records, a new contact will be created using the passed authentication data as the contact identifier.

If your account is configured to use the Cordial generated cID as the primary contact identifier, the authentication object value can be null. In this case, a contact record will be created and assigned a new cID.

Example of adding or updating a contact

This example uses email as the contact identifier. Other contact identifier key/value pairs such as cID: '58d2fc99ac0c8117814d4e78' and customKey: 'cust-id-123' can be used in the same manner.

var auth_data = {
	email: 'fred@example.com'
};
var contact_data = {
    'channels': {
        'email': {
            'subscribeStatus': 'subscribed'
        }
    },
    'first_name': 'Fred',
    'age': '32',
    'platinum': true
};
crdl('contact', auth_data, contact_data);

The use of subscribeStatus key is situational and may not be necessary for all contact creation and update calls.

Subscribe status should only be set to subscribed if the contact has explicitly consented to receive promotional messages. The default subscribe status is none.

For example, if during the checkout process a new contact chooses not to receive promotional emails, it is not necessary to explicitly set their subscribe status to unsubscribed, being that as a new contact without prior subscriptions, their subscribe status is initially set to none. The best way to accomplish this is to leave the subscribeStatus key out of the call entirely.

If, however, the contact indicates by checking a box (or some other way) that they would like to receive promotional emails, the subscribeStatus key with the value of subscribed should be passed as demonstrated here:

var contact_data = {};
contact_data.channels = {};
contact_data.channels.email = {};
contact_data.channels.email.address = 'mark@example.com';
if(your_logic_for_box_checked){
  contact_data.channels.email.subscribeStatus = 'subscribed';
}
var auth_data = {};
auth_data.email = contact_data.channels.email.address;
crdl('contact', auth_data, contact_data);

Example of updating a contact's subscribe status to subscribed

Here's an example of using the forceSubscribe parameter to update a contact's subscribe status to subscribed if currently set to unsubscribed.

crdl('contact',
    {email: 'mark@example.com'},
    {'channels.email.subscribeStatus': 'subscribed'},
    {'forceSubscribe': {email: true}, 'upsert': true} 
);

Example of adding or updating a contact if authentication data is not available

If authentication data is not available (null), the current session BID will be used to look up and update any existing records matching the same BID. If the current session BID is not associated with any of the existing records, the call will be newly added and tracked in the anonymous history collection.

var auth_data = {
	'email': null
};
var contact_data = {
    'platinum': false
};
crdl('contact', auth_data, contact_data);

Examples of working with arrays

var contact_data = {
    'first_array': {'add': [1234]},
    'second_array': {'remove': ['apple']},
    'third_array': [1234, 5678]
};
crdl('contact', auth_data, contact_data);

crdl(event) - Track custom events

Events are stored in the contact activities collection. You can track an event by calling crdl(event) with the event action name and optional event properties object.

crdl('event', 'action_name', properties);

The event action name may be whatever you like, barring a select number of reserved event names.

Reserved event names

The following action names are already used for Cordial system events and should not be used for custom events:

  • click
  • open
  • message-sent
  • bounce
  • optout
  • pageView

Properties object

You can optionally pass a properties object of key/value pairs describing the event. Property keys may be custom-named.

Property keys consisting of numeric-only values, like 57, or keys containing a period, such as shoes.color, will be stripped.

Example of adding a custom named event to the contact activities collection

In the example below, a custom named event with the action name browse will be tracked and added to the contact activities collection.

var properties = {
    "category": "Shirts",
    "url": "http://example.com/category/shirts"
};
	
crdl('event', 'browse', properties); 

Example API response of a custom event in the contact activities collection

Below is an example of how the event data is stored within the contact activities collection. Note that each event will be given a timestamp, an event _id and a cID.

{
    "cID": "58d30719ac0c8117814da1f3",
    "_id": "5902468650c860b06da54183",
    "properties": {
        "category": "shirts",
        "url": "http://example.com/category/shirts",
        "time": "2024-10-27T19:20:50+0000"
    },
    "action": "browse",
    "time": "2024-10-27T19:20:50+0000",
    "email": "fred@example.com"
}

Search and segment on custom events

The property object's key/value pairs can be used for filtering the browse events for creating audiences. For example, an audience filter can be created to query all contacts who were tracked for a browse event. Additionally, a filter can be added to the rule that queries all contacts who were tracked for a browse event where the category is shirts.

crdl(cartitem) - Update cart items

Each contact record contains a cart object stored within the contacts collection. A user must first be in the Cordial contacts collection before adding cart information.

To add items to the cart, we recommend using three methods together that will:

  • Clear the cart
  • Add items to the cart
  • Create a custom-named event called cart
crdl([
    ['cart', 'clear'],
    ['cartitem', 'add' , cart_data], 
    ['event', 'cart']
]);

Cart item object

* Required

Parameter Description Type
* productID Product identifier string
* sku Stock keeping unit/item number string
* category Item category string
* name Item name string
description Item description string
qty<></> Quantity in the cart integer
itemPrice Price per item float
url Link to the item string
images image names or paths array
attr attribute value pairs

object

properties custom key-value pairs

object

Example of updating the cart in the contacts collection

var cart_data = [{
    'productID': '1234',
    'sku':'1234-red',
    'category':'shirts',
    'name':'Red Shirt',
    'images':['http://example.com/image1.jpg','http://example.com/image2.jpg'],
    'description':'A cool red shirt.',
    'qty': 1, 
    'itemPrice': 10.20,
    'url':'http://example.com/pdp/1234',
    'attr': {
        'manufacturer': 'ExampleCo',
        'size': 'L' 
    }
},
{
'productID': '5678',
    'sku':'5678-blue',
    'category':'shirts',
    'name':'Blue Shirt',
    'images':['http://example.com/image1.jpg','http://example.com/image2.jpg'],
    'description':'A bright blue shirt.',
    'qty': 2, 
    'itemPrice': 10.20,
    'url':'http://example.com/pdp/5678',
    'attr': {
        'manufacturer': 'ExampleCo',
        'size': 'L' 
    }
}];

crdl([
    ['cart', 'clear'],
    ['cartitem', 'add' , cart_data], 
    ['event', 'cart']
]);

Example API response of the cart object from the contacts collection

Below is an example of how the cart data is stored within a contact's profile of the contacts collection.

The cartitem amount is automatically calculated (itemPrice x qty) and cart totalAmount is automatically calculated as the sum of all cart item amounts.

"cart": {
    "cartitems": [{
        "productID": "1234",
        "sku": "1234-red",
        "category": "shirts",
        "name": "Red Shirt",
        "images": [
            "http://example.com/image1.jpg",
            "http://example.com/image2.jpg"
        ],
        "description": "A cool red shirt.",
        "qty": 1,
        "itemPrice": 10.2,
        "url": "http://example.com/pdp/1234",
        "attr": {
            "manufacturer": "ExampleCo",
            "size": "L"
        },
        "amount": 10.2
    },
    {
        "productID": "5678",
        "sku": "5678-blue",
        "category": "shirts",
        "name": "Blue Shirt",
        "images": [
            "http://example.com/image1.jpg",
            "http://example.com/image2.jpg"
        ],
        "description": "A bright blue shirt.",
        "qty": 2,
        "itemPrice": 10.2,
        "url": "http://example.com/pdp/5678",
        "attr": {
            "manufacturer": "ExampleCo",
            "size": "L"
        },
        "amount": 20.4
    }],
    "totalAmount": 30.6,
    "lm": "2018-09-27T22:29:49+0000"
}

crdl(order) - Add orders

Calling crdl(order) will add orders to the orders collection with a new record for the individual contact.

The JavaScript Listener must explicitly be allowed to post order data to your account. If you plan to post order data via JavaScript, please contact your CSM to request this feature.

To add an order, we recommend using three methods together that will:

  • Clear the cart
  • Add the order data
  • Create a custom named event called order
crdl([
    ['cart', 'clear'],
    ['order', 'add' , order_data], 
    ['event', 'order']
]);

Order object

* Required

Base level parameters

Parameter Type Description Example
* orderID string Unique identifier assigned for the order. 33451
* cID string Unique primary or secondary contact identifier (key/value pair) to look up and reference the contact.

cID: "1234abcd" or

email: "mikesmith@example.com"

* purchaseDate string A date value signifying the purchase data and time. Date format is ISO 8601.

2025-01-09T22:47:12+0000

linkID string Cordial ID that represents the message and link. * Required to track revenue attribution to a specific link. 45:55....aef:1
mcID string Cordial ID that represents the account, contact, and the message. * Required to track revenue attribution to an email. 45:55....aef:1
msID string Cordial ID that represents the  message. 45:55....aef:1
customerID string An ID value assigned by the eCommerce or CRM system. abc123
properties object

Key value pairs describing the properties of the order.

"currency": "USD"
totalAmount float Auto-calculated as the sum of each item.amount 235.99
tax float The amount of the tax 22.50
shippingAndHandling float The amount charged for shipping and handling. 0.0

shippingAdress and billingAddress object parameters

name string The name of the person or company making the order and/or who the order will be shipped to Mark Smith
address string Defines the street address 13130 Silverlake Road
city string Defines the city Los Angeles
state string Defines the state CA
postalCode integer Defines the postal code 90028
country string Defines the country USA

items object parameters

The items object is optionalbut, if included, productID, sku, category, and name parameters are required.

* productID string A unique identifier for the product. 1234abcd
* sku string The stock keeping unit value for a particular item RF-WP33286-21
* category string The category given to the particular item Major Appliance
* name string The name of the product S22-Refrigerator
qty integer The number of items purchased. Defaults to 1 if not passed. 2
itemPrice float The item price 29.95
amount float Auto-calculated as qty x itemPrice. If a value not equal to qty x itemPrice is passed, it will be overwritten. 59.90
description string Description of the product Great product!
url string Link to the product https://myproduct.com
images array A comma separated array of image file locations. Use an empty array [] as default if no values exist. "https://example.com/pic.jpg"
attr object Key value pairs describing attributes of the product. Values added cannot be searched using the Audience Builder or within Smarty for personalization.

"size":"large",
"color":"red"

properties object Can be used in place of the attr key. Values added can be searched using the Audience Builder and within Smarty for personalization, if searching of nested order properties is enabled in the account.

"brands":["Cool Brand",

"Other Cool Brand"], "return_date": "2025-07-01 00:00:00"

tags array A comma separated array of values to describe the product. Only accepts alphanumeric characters or dashes. "office","office-supplies"

discountApplication object parameters

If discountApplication is included, type and amount are required.

discountApplication object

Calculates a specified discount to arrive at a final sales price.

Calculate the final amount as: totalAmount = totalAmount - discountApplication.amount 

When discountApplication.amount is zero or not present: Calculate totalAmount without any changes.

For a $10 discount:
"discountApplication": {
    "type": "fixed",
    "amount": 10.00
  }
type string

Type of discount. This API accepts discounts of fixed amounts.

fixed
amount integer

amount of discount

10.00

Example of adding an order to the orders collection

var order_data = {
  "orderID": "33451",
  "email": "marksmith@example.com",
  "purchaseDate": "2025-01-09T22:47:12+0000",
  "linkID": "55373eed6c87669bw",
  "mcID": "45:55373eed6c87669bwewewee7:ot:55375ba27ec3343a77ce07ec:1422343949",
  "customerID": "5432225",
  "properties": {
    "color": "red",
    "size": "large",
    "currency": "USD"
  },
  "shippingAddress": {
    "name": "Mark Smith",
    "address": "13130 Silverlake Road",
    "city": "Los Angeles",
    "state": "CA",
    "postalCode": 92332,
    "country": "USA"
  },
  "billingAddress": {
    "name": " Mark Smith ",
    "address": "13130 Silverlake Road",
    "city": "Los Angeles",
    "state": "CA",
    "postalCode": 92332,
    "country": "USA"
  },
  "items": [
    {
      "productID": "1234abcd",
      "sku": "ssd-2344-15",
      "description": "This shirt is amazing!",
      "category": "Shirts",
      "name": "Awesome Flannel",
      "qty": 1,
      "url": "https://awesomeflannels.com/1234abcd",
      "itemPrice": 129.95,
      "images": [
        "https://awesomeflannels.com/image_1.jpg",
        "https://awesomeflannels.com/image_2.jpg"
      ],
      "tags": [
        "flannels",
        "winter"
      ],
      "properties": {
        "brands": [
          "Cool Brand",
          "Other Cool Brand"
        ],
        "return_date": "2025-07-09T22:47:12+0000"
      },
      "attr": {
        "color": "red",
        "size": "large"
      }
    }
  ],
  "discountApplication": {
    "type": "fixed",
    "amount": 10.00
  },
  "tax": 7,
  "shippingAndHandling": 0
};
	
crdl([
    ['cart', 'clear'],
    ['order', 'add', order_data],
    ['event', 'order']
]);

Example API response of an order from the orders collection

{
  "_id": "5bad60450190d43159af5a2b",
  "orderID": "33451",
  "email": "marksmith@example.com",
  "purchaseDate": "2025-01-09T22:47:12+0000",
  "linkID": "55373eed6c87669bw",
  "mcID": "45:55373eed6c87669bwewewee7:ot:55375ba27ec3343a77ce07ec:1422343949",
  "customerID": "5432225",
  "properties": {
    "color": "red",
    "size": "large",
    "currency": "USD"
  },
  "shippingAddress": {
    "name": "Mark Smith",
    "address": "13130 Silverlake Road",
    "city": "Los Angeles",
    "state": "CA",
    "postalCode": 92332,
    "country": "USA"
  },
  "billingAddress": {
    "name": " Mark Smith ",
    "address": "13130 Silverlake Road",
    "city": "Los Angeles",
    "state": "CA",
    "postalCode": 92332,
    "country": "USA"
  },
  "items": [
    {
      "productID": "1234abcd",
      "sku": "ssd-2344-15",
      "description": "This shirt is amazing!",
      "category": "Shirts",
      "name": "Awesome Flannel",
      "qty": 1,
      "url": "https://awesomeflannels.com/1234abcd",
      "itemPrice": 129.95,
      "images": [
        "https://awesomeflannels.com/image_1.jpg",
        "https://awesomeflannels.com/image_2.jpg"
      ],
      "tags": [
        "flannels",
        "winter"
      ],
      "properties": {
        "brands": [
          "Cool Brand",
          "Other Cool Brand"
        ],
        "return_date": "2025-07-09T22:47:12+0000"
      },
      "attr": {
        "color": "red",
        "size": "large"
      }
    }
  ],
  "discountApplication": {
    "type": "fixed",
    "amount": 10.00
  },
  "tax": 7,
  "shippingAndHandling": 0
}

crdl(param-store) - Store parameters

If crdl(param-store) is set, the track script will pull values out of the URL query string for any of the defined keys. The values will be stored in cookies and will be available for retrieval as variables. Stored parameters can be used to track and run reports on Google AdWords, traffic sources or other URL query string values.

For example, if you use an ad service to drive traffic, your URLs may look like this:

http://mydomain.com?utm_source=google&utm_campaign=1234.

You can tell the embedded script which URL query string parameters to listen for:

crdl('param-store', "utm_source,utm_campaign");

The listener will now look for those query string keys and store their values in a cookie. The values are automatically available to you as variables in an anonymous callback function. For example:

crdl('param-store', 'utm_source,utm_campaign');
crdl('event', 'browse', function (cookieData, browser, contact, account) {
var eventProperties = {};
if (cookieData.utm_medium) {
eventProperties.utm_medium = cookieData.utm_medium;
}
if (cookieData.utm_medium) {
eventProperties.utm_source = cookieData.utm_source;
}
return eventProperties;
});

You can tell the script to listen for specific query parameters, as long as the keys in the URL are alphanumerical. The keys may also contain: - and _.  Multiple keys should be comma separated.

You can use the variables in a number of ways, but a common use case would be to pass them as attribute values. The following example assumes an account with attributes called source and campaign. When adding or updating a contact, you could pass the following variables.

crdl('contact', {email: 'name@example.com'}, function (cookieData, browser, contact, account) {
var contactData = {};
if (cookieData.utm_medium) {
contactData.utm_medium = cookieData.utm_medium;
}
if (cookieData.utm_medium) {
contactData.utm_source = cookieData.utm_source;
}
return contactData;
});

If the contact arrived at the page from the URL above, their profile would include the following:

"source": "google",
"campaign": "1234",
...

crdl(forget) - Clear cookies

Calling crdl('forget') will clear the cookies and assign a new browser ID. Useful for logout events and cleaning the current browsing session.

crdl('forget');

crdl(debug) - Debug settings

Calling crdl('debug') will print out your JS listener settings in the console, including cookies identifiers that have been set from an email click.

crdl('debug');

Comments

0 comments

Please sign in to leave a comment.