The Intent Tag uses JavaScript to track user behaviours and dispatches custom events based on modelled inferences in the backend.
Installation
Intent Tracking Snippet
The Intent Tag SDK exposes the intent object on the global window context.
The basic snippet installation is as follows - replace the <token>
values with your own values defined in the table below:
<script type="text/javascript">
window.intent = window.intent || {};
window.intent.dataLayer = window.intent.dataLayer || [];
window.intent.config = {
ingestionId: <ingestion_id>,
iso31661CountryCode: <country_code>,
iso6391LanguageCode: <language_code>,
};
(function() {
var scriptToLoad = "https://intentclientscriptslon.s3.eu-west-2.amazonaws.com/intent-v3.js";
try{!function(){var t,e,c;t=scriptToLoad,e=function(){},(c=document.createElement("script")).setAttribute("src",t),c.setAttribute("async",!0),c.onload=e,document.body.appendChild(c)}()}catch(t){}
})();
</script>
window.intent.config properties
Name | Type | Required | Description |
ingestionId | string | Required | Your Ingestion ID, provided to you by your Made With Intent account manager. The ingestion ID identifies the site property instance against which all reporting, segmentation is carried out. |
iso31661CountryCode | string | Required | 3-letter currency code corresponding to active site currency, irrespective of the user locale. Should conform to ISO 31661, but may in some cases return a non-standard region encomapssing values such as ‘EUR’ or ‘ROW’. |
iso6391LanguageCode | string | Required | The 2-letter ISO6391 current site language code, e.g. ‘en’ or ‘de’. |
hooks | Object | Optional | Config-driven hooks you can use to piggy back onto MWI events and modify core tracking behaviour. More info here |
contextOverride | Object | Optional | Override window, document and navigator contexts. This is useful in sandboxed environments where directly referencing the parent window, document or navigator is not possible. Used to read properties such as |
dataLayer | Object | Optional | A reference to your GTM dataLayer, window.dataLayer by default. Note that if the dataLayer exists, events will not be pushed to it. |
disableDatalayer | Boolean | Optional | Prevent writing Made with Intent events to your GTM datalayer. |
Events
Track Page Views
Send the page view event every time a new page is viewed. If the page is a product page, you should also send product detail ecommerce data.
The following code dispatches the page view event along with ecommerce data if available.
window.intent.dataLayer.push({
type: 'Pageview',
data: {
page_type: <page_type>,
page_category: <page_category>, // e.g. 'watches'
product_tags: {
product_name: <product_name>,
product_sku: <sku>,
product_price: <price>,
product_currency: <currency>,
product_brand: <brand>,
product_category: <category>,
product_subcategory: <subcategory>,
product_image_url: <image_url>,
product_rating: <rating>,
product_review_count: <review_count>,
product_availability: <availability>,
}
}
});
Arguments
Name | Type | Required | Description |
<page_type> | string | Required | The page type of the current page. Required. Values should be one of: |
<sku> | string | Optional | Unique product identifier |
<price> | string | Optional | The price of the product |
<currency> | string | Optional | 3-letter currency code corresponding to active site currency, irrespective of the user locale. Should conform to ISO 4127. |
<brand> | string | Optional | The product brand, e.g. ‘Avengers’ |
<category> | string | Optional | The product top-level category, e.g. ‘footwear’ |
<subcategory> | string | Optional | The product subcategory, e.g. ‘trainers’ |
<image_url> | string | Optional | The full path to the image URL |
<rating> | string | Optional | The rating of the product as per your own rating system, e.g. ‘4.8’ |
<review_count> | number | Optional | The number of reviews against this product |
<availability> | number | Optional | 0 if out of stock, 1 if the product is available // |
Track Add to Cart
Send an add to cart event every time a product is added to cart.
The following code dispatches the add to cart event along with ecommerce data if available.
window.intent.dataLayer.push({
type: 'AddToCart',
data: {
product_name: <product_name>,
product_sku: <sku>,
product_price: <price>,
product_currency: <currency>,
product_brand: <brand>,
product_category: <category>,
product_subcategory: <subcategory>,
product_image_url: <image_url>,
product_rating: <rating>,
product_review_count: <review_count>,
product_availability: <availability>,
}
});
Arguments
Name | Type | Required | Description |
<sku> | string | Optional | Unique product identifier |
<price> | string | Optional | The price of the product added to cart |
<currency> | string | Optional | 3-letter currency code corresponding to active site currency, irrespective of the user locale. Should conform to ISO 4127. |
<brand> | string | Optional | The product brand, e.g. ‘Avengers’ |
<category> | string | Optional | The product top-level category, e.g. ‘footwear’ |
<subcategory> | string | Optional | The product subcategory, e.g. ‘trainers’ |
<image_url> | string | Optional | The full path to the image URL |
<rating> | string | Optional | The rating of the product as per your own rating system, e.g. ‘4.8’ |
<review_count> | number | Optional | The number of reviews against this product |
<availability> | number | Optional | 0 if out of stock, 1 if the product is available |
Track Conversions
Send the conversion event on the page of your website where someone makes a purchase. For example, you could add the event on the confirmation page that appears when someone makes a purchase.
The following code dispatches the event along with ecommerce data from your order.
window.intent.dataLayer.push({
type: 'Conversion',
data: {
currency: <currency>,
shipping_fee: <shipping>,
voucher_code: <voucher>,
tax_value: <tax>,
discount_value: <discount>,
order_value: <value>,
order_quantity: <quantity>,
order_items: [
{
product_id: <product_id>,
item_value: <item_value>,
item_quantity: <quantity>,
item_discount_value: <discount>,
},
... 1 or more ...
]
}
});
Arguments
All arguments are optional but strongly encouraged. The more information you provide the more accurately we can make inferences based on user behaviour and enables ecommerce reporting and segment creation.
Name | Type | Description |
<currency> | string | 3-letter currency code corresponding to active site currency, irrespective of the user locale. Should conform to ISO 4127. |
<shipping_fee> | number | Shipping costs paid by customer in the currency specified, including decimal part. |
<voucher> | string | The voucher or coupon code that a user has used. Note: you should not pass the voucher code if it contains or exists as PII data. Global and frequent reuse codes are usually acceptable. |
<tax> | number | The amount of tax the user has paid on this order. |
<discount> | number | The discount amount if applicable. |
<value> | number | The total order value inclusive of all taxies and shipping |
<quantity> | number | The number of items in the order |
order_items<product_id> | string | The line item SKU identifier |
order_items<item_value> | number | The price of the line item in the order |
order_items<quantity> | number | The quantity of this line item that the user purchased |
order_items<discount> | number | The value of the discount on the line item. |
Verify data collection
You can enable debugging by setting intent_debug to events in local storage. Running the following code in DevTools will do this for you:
localStorage.setItem('intent_debug', 'events');
In the DevTools console, you should see that events are being sent and the structures of those events. Ensure that all field values are populated as expected.
Hooks
You can define hooks in your config to modify core tracking behaviour. Hooks are async functions that are fired at different times during the lifecycle of the script.
Hooks are advanced functionality and we normally suggest you omit declaring hooks in the config, however, examples of how you might use them are given below:
Defining Hooks
window.intent.config = {
ingestionId: <ingestion_id>,
iso31661CountryCode: <country_code>,
iso6391LanguageCode: <language_code>,
hooks: {
async inference({inferenceData}) {
},
async click({evt}) {
},
async pageview(pageType) {
},
async run({poller}) {
}
}
};
Name | Type | Required | Description |
hooks.inference | function | Optional | This hook is fired every time an event is dispatched and an inference response is received |
hooks.click | function | Optional | This hook is fired every time a click event is dispatched. |
hooks.pageview | function | Optional | This hook is fired every time a page view event is dispatched. |
hooks.run | function | Optional | This hook is fired at the start of the Intent script for each page view. |
Examples
Preventing script execution until the GTM datalayer is available
async run({poller}) {
const didConsent = await poller(
() => {
return !!window.dataLayer;
},
60000, // timeout in milliseconds
200, // poll frequency in milliseconds
);
if(!didConsent) {
return false // returning false prevents further execution of MWI tracking
}
}
Preventing clicks being tracked against certain elements
async click({evt}) {
if(evt && evt.target && evt.target.closest('.ignored')) {
return false; // The clicked element is inside an ignore container, bail out
} else {
return true;
}
}
Using Intent Data
Event handling
A number of custom events are dispatched on the document. You can register event listeners on the document before the Intent script has loaded.
Inferences
When events are tracked, you’ll get a modelled data response.
intent.event.sent
Example
document.addEventListener('intent.event.sent', (evt) => {
const intentData = evt.detail.data;
console.table(intentData.intent);
console.table(intentData.buying_stage);
});
Output
(index) | latest | max | latest_pctile | latest_label | max_pctile | max_label |
xc | 0.0083 | 0.079 | 21 | 'Low' | 79 | 'Medium' |
xr | 0.47 | 0.5 | 64 | 'Medium' | 69 | 'Medium' |
xe | 0.23 | 0.38 | 74 | 'Medium' | 89 | 'High' |
xatc | 0.028 | 0.33 | 16 | 'Low' | 88 | 'High' |
xp | 0.21 | 0.32 | 9 | 'Low' | 21 | 'Low' |
(index) | Value |
label | 'Browsing' |
max_label | 'Deciding' |
journey | 'Browsing > Deciding > Browsing > Evaluating > Browsing' |
Last Inference
You can read the last inference data from local storage
const store = localStorage.getItem('intent.inference.last');
if (store) {
const jsonData = JSON.parse(store);
console.log(jsonData.data);
}
Segment and trigger matching
You can copy segment and trigger matching code from the Made with Intent dashboard.
Segment Matching
Custom and pre-built segments are matched by listening for a custom event to be dispatched. Note that the event is fired every time that the segment matches, so you may want to throttle the execution of code in the callback function.
document.addEventListener(
'intent.segmentation.match.' + <segment_id>,
function(e) {
console.log('segment matched');
}
);
Trigger Matching
Triggers events are only dispatched when the trigger conditions are met, in addition to the current user being in the defined segment.
document.addEventListener(
'intent.segmentation.trigger.' + <trigger_id>,
function(e) {
console.log('segment matched and trigger conditions met');
}
);