JavaScript Tracking SDK (tracker.js)
The tracker.js SDK connects your front-end web properties directly to Keystone CDP. It provides a highly resilient queue designed to buffer events if network connectivity drops and automatically provisions identity tracking.
Installation
Provide the SDK snippet in the <head> of your website.
<script
src="https://<your-cdp-domain>/v1/js/tracker.js"
data-api-key="your_public_tracking_key"
></script>
data-api-key: The Scoped API Key generated via the CDP Admin UI.data-endpoint: (Optional) Override the ingestion endpoint manually if you are routing through a proxy.
Note: The tracker is proxy-aware and will dynamically map its ingestion path to /api/ingest relative to where it was loaded if data-endpoint is omitted.
The Methods
The SDK exposes a global window.keystone object. You can safely call this object immediately, even before the script is fully downloaded, because the queue buffers all early calls.
1. The identify Call
This links an anonymous browser session directly to an official customer identity.
// Bare minimum:
keystone('identify', 'user_12345');
// Identity with traits (Highly Recommended):
keystone('identify', 'user_12345', {
email: "[email protected]",
name: "Sarah Connor",
plan: "enterprise"
});
When identify is called, the SDK attaches the known ID to all subsequent events in that session.
2. The track Call
Records an action the user performed. Provide a string name for the event and an optional object containing its properties.
keystone('track', 'Added to Cart', {
product_id: "P-789",
sku: "T-SHIRT-BLK-L",
price: 45.00,
currency: "USD"
});
Auto-Inception Note: If you include order_id inside the properties of any track call, Keystone automatically treats the event as an Order Lifecycle event. A synthetic order will be spawned and progressed in the background database automatically.
3. The page Call
Records a page view.
// Defaults to document.title
keystone('page');
// Giving it an explicit name & properties
keystone('page', 'Checkout Overview', {
url: "/checkout",
cart_value: 120.00
});
4. Direct Push Object Notation
In addition to calling the global keystone() function, you can directly push event objects into the keystoneData queue. This is often easier when dynamically generating payloads natively from backend templates or tag managers.
Identify User
keystoneData.push({
type: 'identify',
userId: 'USER_123',
traits: {
email: '[email protected]',
plan: 'premium'
}
});
Update Customer Profile with Demographic Data
keystoneData.push({
type: 'identify',
userId: 'USER_123',
traits: {
first_name: 'John',
last_name: 'Doe',
email: '[email protected]',
primary_phone: '+15550199',
primary_address: {
address_1: '123 Main St',
city: 'New York',
state_province: 'NY',
postal_code: '10001',
country: 'USA'
},
demographics: [
{ key: 'age_group', value: '25-34', type: 'string' },
{ key: 'income_tier', value: 'high', type: 'string' }
]
}
});
Track Product View
keystoneData.push({
type: 'track',
event: 'Product Viewed',
properties: {
product_id: 'PROD_001',
name: 'Premium Widget',
price: 99.99,
category: 'Electronics',
url: window.location.href
}
});
Track Order
keystoneData.push({
type: 'track',
event: 'Order Completed',
properties: {
order_id: 'ORD_99283',
total: 129.99,
currency: 'USD',
products: [
{ product_id: 'PROD_001', quantity: 1, price: 99.99 },
{ product_id: 'ACC_002', quantity: 2, price: 15.00 }
]
}
});
Form Submission (Example)
// Example: Tracking a newsletter signup
document.querySelector('#signup-form').addEventListener('submit', function(e) {
const email = document.querySelector('#email-input').value;
keystoneData.push({
type: 'track',
event: 'Form Submitted',
properties: {
form_id: 'newsletter_footer',
form_name: 'Weekly Newsletter'
}
});
// Also identify if new info is available
keystoneData.push({
type: 'identify',
traits: { email: email }
});
});
Identity Resilience
The tracker.js heavily relies on a hybrid cookie/localStorage implementation to persist the keystone_anonymous_id.
The tracker uses Domain Root tracking. If installed on shop.example.com, the cookie drops at .example.com allowing you to seamlessly track user progression from blog.example.com all the way to checkout without the identifier fragmenting.