Getting Started
Our JS SDK allows you to create and deliver Experiments and Feature Flags to your users. Once setup, you can also leverage the Visual Web Editor to make changes without needing to touch code again!
To fully utilize the power of Taplytics.js, get started by initializing Taplytics using one of either the Synchronous or Asynchronous initialization methods.
1A Synchronous script loading
To best utilize Taplytics JS SDK you will want to install it as a synchronous loading script. This will ensure your users never see your content switching from baseline to their bucketed variations.
We recommend installing the Taplytics JS SDK script as high as possible in your <head>
tag, ideally before any other analytics tools or other scripts are loaded.
To install the Taplytics JS SDK synchronously, use one of following methods to load the Taplytics SDK. Then call TaplyticsInit
with your JS_SDK_Key
found on the Taplytics web dashboard:
i) Option 1: Using the CDN
<script type="text/javascript" src="https://cdn.taplytics.com/syncLoader.min.js"></script>
<script>
TaplyticsInit({
token: "JS_SDK_Key"
});
</script>
ii ) Option 2: Inline
<script type="text/javascript">
var TaplyticsInit=function(t){var e={};function r(n){if(e[n])return e[n].exports;var o=e[n]={i:n,l:!1,exports:{}};return t[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}return r.m=t,r.c=e,r.d=function(t,e,n){r.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},r.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},r.t=function(t,e){if(1&e&&(t=r(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var o in t)r.d(n,o,function(e){return t[e]}.bind(null,o));return n},r.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return r.d(e,"a",e),e},r.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},r.p="",r(r.s=0)}([function(t,e,r){"use strict";function n(t,e){var r=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),r.push.apply(r,n)}return r}function o(t,e,r){return e in t?Object.defineProperty(t,e,{value:r,enumerable:!0,configurable:!0,writable:!0}):t[e]=r,t}function i(t,e){if(null==t)return{};var r,n,o=function(t,e){if(null==t)return{};var r,n,o={},i=Object.keys(t);for(n=0;n<i.length;n++)r=i[n],e.indexOf(r)>=0||(o[r]=t[r]);return o}(t,e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(n=0;n<i.length;n++)r=i[n],e.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(t,r)&&(o[r]=t[r])}return o}function c(t){for(var e=decodeURIComponent(document.cookie).split(";"),r=t+"=",n=0;n<e.length;n++){for(var o=e[n];" "===o.charAt(0);)o=o.substring(1);if(0===o.indexOf(r))return o.substring(r.length,o.length)}return""}function u(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=t.token,r=t.env,u=t.test_experiments,a=t.user_attributes,s=t.alias_host,f=t.version,l=i(t,["token","env","test_experiments","user_attributes","alias_host","version"]);if(!e)throw new Error("Project token must be provided in order to initialize Taplytics!");var p=(s||{}).api_host,b="https://".concat(r?"".concat(r):"js",".taplytics.com"),d="".concat(p||b,"/jssdk/").concat(f?f.concat("/"):"").concat(e,".min.js"),y=function(t){for(var e=1;e<arguments.length;e++){var r=null!=arguments[e]?arguments[e]:{};e%2?n(r,!0).forEach((function(e){o(t,e,r[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(r)):n(r).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(r,e))}))}return t}({test_experiments:u&&JSON.stringify(u),user_attributes:a&&JSON.stringify(a),alias_host:s&&JSON.stringify(s),env:r},l,{uid:c("_tl_uid"),ad:c("_tl_duuid"),sync:!0}),O=Object.keys(y).filter((function(t){return void 0!==y[t]&&null!==y[t]&&""!==y[t]})).map((function(t){return"".concat(t,"=").concat(encodeURIComponent(y[t]))})).join("&");document.write("<script type='text/javascript' src='".concat(d).concat(O?"?".concat(O):"","'><\/script>"))}r.r(e),r.d(e,"default",(function(){return u}))}]).default;
TaplyticsInit({
token: "JS_SDK_Key"
});
</script>
Example implementation:
<!DOCTYPE html>
<html lang="en">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
<!-- Add other meta information -->
<!-- Add stylesheets -->
<script type="text/javascript">
var TaplyticsInit=function(t){var e={};function r(n){if(e[n])return e[n].exports;var o=e[n]={i:n,l:!1,exports:{}};return t[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}return r.m=t,r.c=e,r.d=function(t,e,n){r.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},r.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},r.t=function(t,e){if(1&e&&(t=r(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var o in t)r.d(n,o,function(e){return t[e]}.bind(null,o));return n},r.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return r.d(e,"a",e),e},r.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},r.p="",r(r.s=0)}([function(t,e,r){"use strict";function n(t,e){var r=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),r.push.apply(r,n)}return r}function o(t,e,r){return e in t?Object.defineProperty(t,e,{value:r,enumerable:!0,configurable:!0,writable:!0}):t[e]=r,t}function i(t,e){if(null==t)return{};var r,n,o=function(t,e){if(null==t)return{};var r,n,o={},i=Object.keys(t);for(n=0;n<i.length;n++)r=i[n],e.indexOf(r)>=0||(o[r]=t[r]);return o}(t,e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(n=0;n<i.length;n++)r=i[n],e.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(t,r)&&(o[r]=t[r])}return o}function c(t){for(var e=decodeURIComponent(document.cookie).split(";"),r=t+"=",n=0;n<e.length;n++){for(var o=e[n];" "===o.charAt(0);)o=o.substring(1);if(0===o.indexOf(r))return o.substring(r.length,o.length)}return""}function u(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=t.token,r=t.env,u=t.test_experiments,a=t.user_attributes,s=t.alias_host,f=t.version,l=i(t,["token","env","test_experiments","user_attributes","alias_host","version"]);if(!e)throw new Error("Project token must be provided in order to initialize Taplytics!");var p=(s||{}).api_host,b="https://".concat(r?"".concat(r):"js",".taplytics.com"),d="".concat(p||b,"/jssdk/").concat(f?f.concat("/"):"").concat(e,".min.js"),y=function(t){for(var e=1;e<arguments.length;e++){var r=null!=arguments[e]?arguments[e]:{};e%2?n(r,!0).forEach((function(e){o(t,e,r[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(r)):n(r).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(r,e))}))}return t}({test_experiments:u&&JSON.stringify(u),user_attributes:a&&JSON.stringify(a),alias_host:s&&JSON.stringify(s),env:r},l,{uid:c("_tl_uid"),ad:c("_tl_duuid"),sync:!0}),O=Object.keys(y).filter((function(t){return void 0!==y[t]&&null!==y[t]&&""!==y[t]})).map((function(t){return"".concat(t,"=").concat(encodeURIComponent(y[t]))})).join("&");document.write("<script type='text/javascript' src='".concat(d).concat(O?"?".concat(O):"","'><\/script>"))}r.r(e),r.d(e,"default",(function(){return u}))}]).default;
TaplyticsInit({
token: "JS_SDK_Key"
});
</script>
<!-- Add other scripts and content -->
</head>
<body>
...
</body>
</html>
Pin SDK version
To pin the SDK to a specific version add the version
option to the TaplyticsInit
call along with the Version Number that you are targeting.
<script type="text/javascript">
var TaplyticsInit=function(t){var e={};function r(n){if(e[n])return e[n].exports;var o=e[n]={i:n,l:!1,exports:{}};return t[n].call(o.exports,o,o.exports,r),o.l=!0,o.exports}return r.m=t,r.c=e,r.d=function(t,e,n){r.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},r.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},r.t=function(t,e){if(1&e&&(t=r(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var n=Object.create(null);if(r.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var o in t)r.d(n,o,function(e){return t[e]}.bind(null,o));return n},r.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return r.d(e,"a",e),e},r.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},r.p="",r(r.s=0)}([function(t,e,r){"use strict";function n(t,e){var r=Object.keys(t);if(Object.getOwnPropertySymbols){var n=Object.getOwnPropertySymbols(t);e&&(n=n.filter((function(e){return Object.getOwnPropertyDescriptor(t,e).enumerable}))),r.push.apply(r,n)}return r}function o(t,e,r){return e in t?Object.defineProperty(t,e,{value:r,enumerable:!0,configurable:!0,writable:!0}):t[e]=r,t}function i(t,e){if(null==t)return{};var r,n,o=function(t,e){if(null==t)return{};var r,n,o={},i=Object.keys(t);for(n=0;n<i.length;n++)r=i[n],e.indexOf(r)>=0||(o[r]=t[r]);return o}(t,e);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(t);for(n=0;n<i.length;n++)r=i[n],e.indexOf(r)>=0||Object.prototype.propertyIsEnumerable.call(t,r)&&(o[r]=t[r])}return o}function c(t){for(var e=decodeURIComponent(document.cookie).split(";"),r=t+"=",n=0;n<e.length;n++){for(var o=e[n];" "===o.charAt(0);)o=o.substring(1);if(0===o.indexOf(r))return o.substring(r.length,o.length)}return""}function u(){var t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},e=t.token,r=t.env,u=t.test_experiments,a=t.user_attributes,s=t.alias_host,f=t.version,l=i(t,["token","env","test_experiments","user_attributes","alias_host","version"]);if(!e)throw new Error("Project token must be provided in order to initialize Taplytics!");var p=(s||{}).api_host,b="https://".concat(r?"".concat(r):"js",".taplytics.com"),d="".concat(p||b,"/jssdk/").concat(f?f.concat("/"):"").concat(e,".min.js"),y=function(t){for(var e=1;e<arguments.length;e++){var r=null!=arguments[e]?arguments[e]:{};e%2?n(r,!0).forEach((function(e){o(t,e,r[e])})):Object.getOwnPropertyDescriptors?Object.defineProperties(t,Object.getOwnPropertyDescriptors(r)):n(r).forEach((function(e){Object.defineProperty(t,e,Object.getOwnPropertyDescriptor(r,e))}))}return t}({test_experiments:u&&JSON.stringify(u),user_attributes:a&&JSON.stringify(a),alias_host:s&&JSON.stringify(s),env:r},l,{uid:c("_tl_uid"),ad:c("_tl_duuid"),sync:!0}),O=Object.keys(y).filter((function(t){return void 0!==y[t]&&null!==y[t]&&""!==y[t]})).map((function(t){return"".concat(t,"=").concat(encodeURIComponent(y[t]))})).join("&");document.write("<script type='text/javascript' src='".concat(d).concat(O?"?".concat(O):"","'><\/script>"))}r.r(e),r.d(e,"default",(function(){return u}))}]).default;
TaplyticsInit({
token: "JS_SDK_Key",
version: 'x.y.z',
...startOptions
})
</script>
Start Options
Start Options allow you to control how certain SDK features function, such as the default request timeout. Simply add them to the TaplyticsInit
call.
Start Option | Type | Description |
---|---|---|
alias_host | Object | This is used to replace the hosts of the urls to bypass adblockers |
auto_page_view | Boolean | Enable or disable to automatically track page views when starting up the sdk |
cookie_domain | String | Set the domain that Taplytics will use to create cookies with. By default Taplytics will use a wildcard version of your top level domain that will work across sub-domains. For example a cookie from web.taplytics.com will be set as .taplytics.com , that will also work on another subdomain such as: new.taplytics.com . |
manual_trigger_edits | Boolean | Turn this ON to prevent applying visual edits automatically by the sdk |
test_experiments | Object | Set an Object containing pairs of experiment/variation combinations as key/value pairs to test with. Docs |
timeout | Number | Set the request timeout in seconds. If requests timeout variables will use the default value, but no events will be saved. The default timeout is 4 seconds. |
user_attributes | Object | Set initial user attributes to be used during initial segmentation. This allows you to set custom data and user attributes that will be used by Taplytics to segment your user into experiments. Format of user attributes defined here. |
adobe_obj_name | String | The adobe_obj_name is optional. The default variable that comes with Adobe Analytics integration is s . The s variable contains all of the tracking tags to be sent to Adobe Analytics for a given visitor. You only need to provide this if you are using a custom variable name. |
track_adobe_analytics | Boolean | Enable Adobe Analytics events to be collected into Taplytics. |
Example:
TaplyticsInit({
token: "JS_SDK_Key",
version: '2.1.0',
timeout: 10,
fast_mode: true,
test_experiments: {
"JS experiment": "Variation 1",
"JS experiment 2": "baseline"
},
user_attributes:{
"email": "[email protected]",
"qa_user": true,
"purchases": 15
}
})
Session Length
A session is defined as user activity from the start of a new session until 30 minutes from last activity logged into Taplytics. If a user has not done anything to trigger updating their user information in Taplytics, we consider their next activity afterwards to be a new session.
You can also manually start a new session using the startNewSession method.
Taplytics.startNewSession();
1B Asynchronous script loading
Note: you only need to load the script once, do not load the synchronous script and the asynchronous script!
To install Taplytics JS SDK asynchronously, you have to include the following snippet into the header or body of your site:
<script type="text/javascript">
!function(){var t=window.Taplytics=window.Taplytics||[];if(window._tlq=window._tlq||[],!t.identify&&!t.loaded){t.loaded=!0,t.funcs=["init","identify","track","page","reset","propertiesLoaded","runningExperiments","variable","codeBlock"],t.mock=function(n){return function(){var e=Array.prototype.slice.call(arguments);return e.unshift(n),window._tlq.push(e),t}};for(var n=0;n<t.funcs.length;n++){var e=t.funcs[n];t[e]=t.mock(e)}t.load=function(){var t=document.createElement("script");t.type="text/javascript",t.async=!0,t.src="//cdn.taplytics.com/taplytics.min.js";var n=document.getElementsByTagName("script")[0];n.parentNode.insertBefore(t,n)},t.load()}}();
</script>
This will load Taplytics.js asynchronously, so it will not affect your page load speed. We advise you use the synchronous script loading for any experiments applying content changes.
Other than that, all you have to do is initialize our SDK by using the init
function:
Taplytics.init("JS_SDK_TOKEN");
Replace JS_SDK_TOKEN
with your JS SDK token. You can find your token in the settings page of your project in the Taplytics dashboard.
When Taplytics.init() should be called
Taplytics.init() should be called if initializing asynchronously only. Calling Taplytics.init() alongside the synchronous script will cause multiple calls to Taplytics, which can result in undesired behaviour.
Note that this will send a page view event to us. If you want to disable the automatic page view event when Taplytics.js is initialized, check the documentation on the init
function here and about calling the page
function manually here.
Pin SDK version
If you would like to pin the JS SDK to a specific SDK version change the //cdn.taplytics.com/taplytics.min.js
url in the snip-it above using the following url where sdk_version
is the version you would like to pin to: //cdn.taplytics.com/jssdk/sdk_version/taplytics.min.js
Start Options
Start options allow you to control how certain SDK features, such as the default request timeout.
Start Option | Type | Description |
---|---|---|
alias_host | Object | This is used to replace the hosts of the urls to bypass adblockers |
auto_page_view | Boolean | Enable or disable to automatically track page views when starting up the sdk |
cookie_domain | String | Set the domain that Taplytics will use to create cookies with. By default Taplytics will use a wildcard version of your top level domain that will work across sub-domains. For example a cookie from web.taplytics.com will be set as .taplytics.com , that will also work on another subdomain such as: new.taplytics.com . |
fast_mode | Boolean | Enables client-side experiment distribution using CDN distributed configuration, but reduces segmentation options. Learn more. |
test_experiments | Object | Set an Object containing pairs of experiment/variation combinations as key/value pairs to test with. Learn more. |
timeout | Number | Set the request timeout in seconds. If requests timeout variables will use the default value, but no events will be saved. The default timeout is 4 seconds. |
user_attributes | Object | Set initial user attributes to be used during initial segmentation. This allows you to set custom data and user attributes that will be used by Taplytics to segment your user into experiments, user attributes set after calling Taplytics.init() won't be used for segmentation until the next session. For the format of user attributes, visit our reference documentation. |
adobe_obj_name | String | The adobe_obj_name is optional. The default variable that comes with Adobe Analytics integration is s . The s variable contains all of the tracking tags to be sent to Adobe Analytics for a given visitor. You only need to provide this if you are using a custom variable name. |
track_adobe_analytics | Boolean | Enable Adobe Analytics events to be collected into Taplytics. |
Example:
Taplytics.init("JS_SDK_TOKEN", {
timeout: 10,
fast_mode: true,
test_experiments: {
"JS experiment": "Variation 1",
"JS experiment 2": "baseline"
},
user_attributes:{
"email": "[email protected]",
"qa_user": true,
"purchases": 15
}
});
Fast Mode
Deprecated: we advise using Synchronous script loading instead.
By default the JS SDK makes a request to Taplytics servers to generate its configuration, this gives us access to advanced segmentation options based on browser information and user data. However if the loading of your website is blocked by a Taplytics variable, you can enable Fast Mode which moves all the experiment distribution to the client-side SDK from Taplytics servers. Your project's configuration for Fast Mode is stored on a globally distributed CDN to reduce load times, however you will lose access to server-side segmentation based on user information.
Adding Fast Mode start option example:
Taplytics.init("JS_SDK_TOKEN", {
fast_mode: true
});
2. Identify Users
Using the identify
function, you can let us know who the current user is on the page. It can also be used to let us know about any user attribute that can be used for segmentation in our system.
We accept a few known attributes and all unknown attributes are saved as custom attributes that can also be used. Read more about the identify
function here.
Here's a quick example:
Taplytics.identify({
email: "[email protected]",
user_id: "abbc-123-axx-123-okl-123",
first_name: "Nima",
last_name: "Gardideh",
age: 23,
gender: "male",
friends_count: 10,
purchases_count: 10,
store_credit: 102.14
});
3. Track Events
You can use the track
function to send us events and let us know what actions the user is performing on the page. You can use these events within Taplytics to create more personalized and rich a/b tests and push notifications.
Here's how to do it:
Taplytics.track("Purchase", 10, {
product_id: 100,
product_name: "Cyan-Pink Shirt",
product_price: 80.00
});
Note that you can send us revenue information by passing a value to the function and any other data that you can use when creating segments within Taplytics. Read more about the track
function here.
4. Track Page Views
As we mentioned earlier, we automatically track page views for you when you initialize our SDK. You will have to call the page
function if you would like to perform the following; rename your page views, attach more information to your page views, or if you're using a one-page web framework (Angular, React, Backbone, Ember, etc.).
You can specify a category, a name, and extra attributes when calling the page function:
Taplytics.page("Product Listings", "Shirts", {
products_count: 100
});
Note that you can call the function by itself without any arguments as well. Read more about the page
function here.
5. Experiments and Feature Flags
To setup code experiments with the Taplytics JS SDK check out the Experiments section here.
To setup feature flags with the Taplytics JS SDK check out the Feature Flags section here.
6. Opt-In/Out
Using the User Opt-In / Opt-Out APIs allows you to simplify the process to get user consent for analytics tracking and experimentation. Calling optOutTracking
will disable all Taplytics analytics tracking and experiments and delete all Taplytics cookies, and calling optInTracking will re-enable all Taplytics analytics tracking and experiments. You can retrieve the current status using: hasUserOptedOutTracking.
function optIn() {
console.log("opt in")
Taplytics.optInTracking();
}
function optOut() {
console.log("opt out")
Taplytics.optOutTracking();
}
function hasOptedOut() {
let hasUserOptedOut = Taplytics.hasUserOptedOutTracking();
console.log(`Has user opted out tracking: ${hasUserOptedOut}`)
}
7. Integrations
Adobe
Adobe Analytics by default uses s.t()
and s.tl()
for tracking page views and link clicks. By setting track_adobe_analytics
variable to true in Taplytics.init
function, We inject our tracking code into the definitions of these functions. So whenever s.t()
or s.tl()
is called on the page, It first sends those events to Taplytics before sending them to Adobe Analytics.
By default, Taplytics assumes adobe analytics tracking variable to be s
. If you use a custom variable, then make sure to provide that during taplytics initialization with adobe_obj_name
variable.
Mixpanel
To activate the Mixpanel integration, turn on the Mixpanel option in the settings of the Taplytics dashboard. The SDK will register super properties on Mixpanel when it starts up in the format:
"TL_Experiments": ["Experiment 1:baseline", "Experiment 2:Variation 2"]
Note: Make sure that Mixpanel is initialized before Taplytics.
8. Adblockers: How to Navigate
CNAME Aliasing
Implementing CNAME aliasing can prevent adblockers from blocking requests to our api servers and our SDK. In order to workaround adblockers, please follow the implementation details below to add the alias_host
start option and update the url to the SDK. In addition, Taplytics also requires a certificate for the domain that you will create a CNAME record for. If you would prefer not to create a certificate and send it to Taplytics, see the “Using a Reverse Proxy” section below.
1. Setup a CNAME on a DNS which points to our API Domains:
https://api-alias.your-domain.com
-> https://api.taplytics.com
https://ping-alias.your-domain.com
-> https://ping.taplytics.com
Once you have generated a CNAME, proceed in modifying your existing JS SDK loading scripts and include the alias_host
start option.
Two options exist in loading the JS SDK. Please follow one of the two options below to successfully load the JS SDK dependent on your configuration.
a) Asynchronous Script Loading
Replace cdn.taplytics.com/taplytics.min.js
with api-alias.your-domain.com/jssdk/
<script type="text/javascript"> !function(){var t=window.Taplytics=window.Taplytics||[];if(window._tlq=window._tlq||[],!t.identify&&!t.loaded){t.loaded=!0,t.funcs=["init","identify","track","page","reset","propertiesLoaded","runningExperiments","variable","codeBlock"],t.mock=function(n){return function(){var e=Array.prototype.slice.call(arguments);return e.unshift(n),window._tlq.push(e),t}};for(var n=0;n<t.funcs.length;n++){var e=t.funcs[n];t[e]=t.mock(e)}t.load=function(){var t=document.createElement("script");t.type="text/javascript",t.async=!0,t.src="//api-alias.your-domain.com/jssdk";var n=document.getElementsByTagName("script")[0];n.parentNode.insertBefore(t,n)},t.load()}}(); </script>
Add the alias_host
start option and your CNAME domains
Taplytics.init("JS_SDK_Key", {
alias_host: {
api_host: 'https://api-alias.your-domain.com',
ping_host: 'https://ping-alias.your-domain.com'
}
});
b) Synchronous Script Loading
Add the alias_host
start option as a URL parameter to the sync loading script
<script type="text/javascript">
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
const alias = {
api_host: 'https://api-alias.your-domain.com',
ping_host: 'https://ping-alias.your-domain.com'
}
const encodedAlias = encodeURIComponent(JSON.stringify(alias));
script.src = `https://api-alias.your-domain.com/jssdk/{JS_SDK_Key}.min.js?alias_host=${encodedAlias}`;
head.appendChild(script);
</script>
2. Generate a new Certificate
You will then need to create a new Certificate for the domain you wish to whitelist. The certificate will contain 4 files, three of which are required:
- cert.pem*
- privkey.pem*
- chain.pem*
- fullchain.pem
Required: cert.pem, privkey.pem, and chain.pem.
To submit your certificate in addition to completing the setup, please contact your CSM or email us directly at [email protected].
Using a Reverse Proxy
Another way to navigate adblockers is to implement a reverse proxy from your server to ours. In this case, rather than using a CNAME to direct traffic from specific subdomains to our API and PING domains, you will need to implement routes on your server that would proxy traffic from your server to ours. Please note: unlike the CNAME option above, this option does not require a certificate to be created.
Below is a sample NginX configuration exemplifying reverse proxies:
...
location /tap-api/ {
proxy_pass https://api.taplytics.com/;
}
location /tap-ping/ {
proxy_pass https://ping.taplytics.com/;
}
...
Once you have implemented routes on your servers, proceed in modifying your existing JS SDK loading scripts and include the alias_host
start option.
Two options exist in loading the JS SDK. Please follow one of the two options below to successfully load the JS SDK dependent on your configuration.
a) Asynchronous Script Loading
Replace cdn.taplytics.com/taplytics.min.js
with your-domain.com/tap-api/jssdk
<script type="text/javascript"> !function(){var t=window.Taplytics=window.Taplytics||[];if(window._tlq=window._tlq||[],!t.identify&&!t.loaded){t.loaded=!0,t.funcs=["init","identify","track","page","reset","propertiesLoaded","runningExperiments","variable","codeBlock"],t.mock=function(n){return function(){var e=Array.prototype.slice.call(arguments);return e.unshift(n),window._tlq.push(e),t}};for(var n=0;n<t.funcs.length;n++){var e=t.funcs[n];t[e]=t.mock(e)}t.load=function(){var t=document.createElement("script");t.type="text/javascript",t.async=!0,t.src="//your-domain.com/tap-api/jssdk";var n=document.getElementsByTagName("script")[0];n.parentNode.insertBefore(t,n)},t.load()}}(); </script>
Add the alias_host
start option and your CNAME domains
Taplytics.init("JS_SDK_Key", {
alias_host: {
api_host: 'https://your-domain.com/tap-api',
ping_host: 'https://your-domain.com/tap-ping'
}
});
b) Synchronous Script Loading
Add the alias_host
start option as a URL parameter to the sync loading script
<script type="text/javascript">
var head = document.getElementsByTagName('head')[0];
var script = document.createElement('script');
script.type = 'text/javascript';
const alias = {
api_host: 'https://your-domain.com/tap-api',
ping_host: 'https://your-domain.com/tap-ping'
}
const encodedAlias = encodeURIComponent(JSON.stringify(alias));
script.src = `https:/https://your-domain.com/tap-api/jssdk/{JS_SDK_Key}.min.js?alias_host=${encodedAlias}`;
head.appendChild(script);
</script>
After completing the steps above, users should be able to freely maneuver around adblockers and prevent them from blocking requests to our api servers and our SDK.
Experiments
Creating experiments is easy, using the Taplytics Javascript SDK you can create code-based experiments with Dynamic Variables or Code Blocks. Continue reading to find out how to set up those up in code below and find instructions on setting up Experiments on the Taplytics dashboard here.
Dynamic Variables
Taplytics variables are values in your website that are controlled by Experiments. Changing the values can update the content or functionality of your website. Variables are reusable between Experiments but may cause issues if they are used in multiple Active Experiments.
There are two types of code variables that you can leverage, synchronous and asynchronous variables. More info on those below.
Synchronous Variables
Due to the synchronous nature of the variable, if it is used before the experiments have been loaded from Taplytics servers, it's value will be the default value rather than the value set for that experiment. This could taint the results of the experiment. In order to prevent this you can ensure that the experiments are loaded before using the variable. This can be done using the propertiesLoaded
method. See example below.
Synchronous variables take two parameters in its constructor:
- Variable Name (String)
- Default Value (String, Number, or Boolean)
The type of the variable is defined by the type of the default value, and can be a String
, Number
or a Boolean
.
For example, using a variable of type String
with propertiesLoaded
:
Taplytics.propertiesLoaded(() => {
var syncVar = Taplytics.variable("JS String", "default");
console.log("JS String Sync value: " + syncVar.value);
});
Asynchronous Variables
Asynchronous variables take care of insuring that the experiments have been loaded before returning a value. This removes any danger of tainting the results of your experiment with bad data. What comes with the insurance of using the correct value is the possibility that the value will not be set immediately. If the variable is constructed before the experiments are loaded, you won't have the correct value until the experiments have finished loading. If the experiments fail to load, then you will be given the default value, as specified in the variables constructor.
Asynchronous variables take three parameters in its constructor:
- Variable Name (String)
- Default Value (String, Number, or Boolean)
- Updated Function (Function)
The type of the variable is defined by the type of the default value, and can be a String
, Number
or a Boolean
.
For example, using a variable of type Number
:
When the SDK has loaded the experiment config from our servers, the updated block will be called with that updated value.
Taplytics.variable("JS Number", 1, (value) => {
// function called when experiment config has loaded and value has been set
console.log("JS Number value: " + value);
});
Note: To see and modify the code variables you've added in code on the dashboard, the SDK must be launched and this code containing the variable or block must be navigated to a least once. This will auto-populate the Experiments dashboard with your newly created variables. You may manually create code variables on the dashboard as well.
Code Blocks
Similar to Dynamic Variables, Taplytics has an option for 'Code Blocks'. Code blocks are linked to Experiments through the Taplytics website very much the same way that Dynamic Variables are, and will be executed based on the configuration of the experiment through the Taplytics dashboard
A Code Block is a function that can be enabled or disabled depending on the variation. If enabled, the function will be executed asynchronously once the experiment config has loaded from our servers. If disabled, the function will not be executed.
Example:
Taplytics.codeBlock("enableFeature", function() {
// enable your feature here
});
A Code Block can be used alongside as many other Code Blocks as you would like to determine a combination that yields the best results. Perhaps there are three different Code Blocks on one view. This means there could be 8 different combinations of Code Blocks being enabled / disabled on that view if you'd like.
Note: To see and modify your code blocks on the dashboard, the SDK must be launched and this code containing the variable or block must be navigated to a least once. This will auto-populate the Experiments dashboard with your newly created variables. You may manually create code blocks on the dashboard as well.
Get Running Experiments
If you would like to see a list of all experiments and variations that are running, use the runningExperiments
function. This will return the current experiments and their variations that the browser is receiving once the SDK has loaded the config from our servers.
The block can return asynchronously once Taplytics config has loaded and will return an Object with experiment names as the key values, and variation names as the values. Example:
Taplytics.runningExperiments(function(expAndVars) {
// Example of expAndVars:
// expAndVars = {
// "Experiment 1": "baseline",
// "Experiment 2": "Variation 1"
//};
});
Feature Flags
Taplytics feature flags operate in synchronous mode. Synchronous feature flags are guaranteed to have the same value for the entire session and will have that value immediately after construction.
if (Taplytics.featureFlagEnabled("featureFlagKey")) {
//Put feature code here, or launch feature from here
}
Due to the synchronous nature of feature flags, if it is used before the feature flags have been loaded from Taplytics servers, it will default to as if the feature flag is not present. In order to prevent this you can ensure that the feature flags are loaded before using the feature flag. This can be done using the propertiesLoaded
method, as an example:
Taplytics.propertiesLoaded((loaded) => {
if (Taplytics.featureFlagEnabled("featureFlagKey")) {
// Put feature code here, or launch feature from here
}
})
Get Running Feature Flags
If you would like to see a list of feature flags that are running on the browser, there exists a getRunningFeatureFlags
function which provides a callback with an object that contains the current active feature flags.
The block can return asynchronously once Taplytics properties have loaded. The feature flags will be provided in an object where the properties are the feature flag key names and their corresponding values are the names of the associated feature flags.
Taplytics.runningFeatureFlags((runningFF) => {
// For example runningFF will contain:
// {
// "featureFlagKey": "My First Feature Flag",
// "key with spaces": "My Second Feature Flag"
// }
});
Test Experiments and Feature Flags
To test/QA specific Experiment and Variation combinations as well as Feature flags, use the test_experiments
option with an Object containing keys of the Experiment or Feature flag names, and values of Variation names (or baseline
).
Taplytics.init("JS_SDK_TOKEN", {
test_experiments: {
"JS experiment": "Variation 1",
"JS experiment 2": "baseline",
"JS Feature Flag": "baseline"
}
});
Reference
Below you will find the APIs that Taplytics.js exposes.
If you haven't already, check out our guide on how to get started with our Javascript SDK here.
init
Usage: Taplytics.init(token, [options])
Instantiates Taplytics.js.
This should be the first function to be called on the page before all other functions. You can find your JS SDK Key in the Settings section of your project.
It also automatically calls the page function (with no arguments) right away. You can disable this in the options.
Arguments
token
(string): Taplytics JS SDK[options]
(Object): The options object.
Options Params | Type | Description |
---|---|---|
timeout | Number | Set the request timeout in seconds. If requests timeout variables will use the default value, but no events will be saved. The default timeout is 4 seconds. |
test_experiments | Object | Set an Object containing pairs of experiment/variation combinations as key/value pairs to test with. Learn more. |
fast_mode | Boolean | Enables client-side experiment distribution using CDN distributed configuration, but reduces segmentation options. Docs |
cookie_domain | String | Set the domain that Taplytics will use to create cookies with. By default Taplytics will use a wildcard version of your top level domain that will work across sub-domains. For example a cookie from web.taplytics.com will be set as .taplytics.com , that will also work on another subdomain such as: new.taplytics.com . |
user_attributes | Object | Set inital user attributes to be used during inital segmenation. This allows you to set custom data and user attributes that will be used by Taplytics to segment your user into experiments, user attributes set after calling Taplytics.init() won't be used for segmentation until the next session. |
Returns
(Object): Returns the Taplytics object on success, useful for chaining. When no token is provided, it returns undefined
.
Example
// Without options
Taplytics.init("JS_SDK_TOKEN");
// With some options
Taplytics.init("JS_SDK_TOKEN", {
auto_page_view: false,
log_level: 1
});
identify
Usage: Taplytics.identify(user_attributes)
Identifies the user that's currently on the page. This helps link their activity on the web with their activity on other platforms (iOS, Android).
You should call this function as soon as a user signs up or has logged in. You should also call it at least once per page.
Arguments
[user_attributes={}]
(Object): User Attributes object.[user_attributes.user_id]
(string/integer): User's ID (optional).[user_attributes.email]
(string): User's Email (optional).[user_attributes.gender]
(string): User's Gender, one ofmale
orfemale
(optional).[user_attributes.age]
(integer): User's age as a number (optional).[user_attributes.firstName]
(integer): User's first name (optional).[user_attributes.lastName]
(integer): User's last name (optional).[user_attributes.name]
(integer): User's full name (optional).[user_attributes.avatarUrl]
(string): User's avatar/profile image URL (optional).[user_attributes.custom_attr_name]
(string/integer/object): Any extra custom attributes (optional).
Returns
(Object): Returns the Taplytics object, useful for chaining.
Example
// With just a few named user attributes
Taplytics.identify({
email: "[email protected]",
age: 23,
gender: "male",
firstName: "Nima",
lastName: "Gardideh"
});
// With non-named custom attributes
Taplytics.identify({
user_id: 1015,
loyalty_group: "very_loyal",
purchases_count: 15,
friends_Count: 800
});
track
Usage: Taplytics.track(event_name, [value], [event_attributes])
Tracks the occurrence of an event for the current visitor (anonymous or identified).
Note that value
is identified as revenue. If you want to send information about the event itself, send it through event_attributes
.
Aliases
This function can also be called as follows:
Taplytics.track(event_name, [event_attributes])
Arguments
event_name
(string): Event name.value
(integer/double): Value of the event (optional).event_attributes
(Object): Event attributes to be sent with the event (optional).
Returns
(Object): Returns the Taplytics object, useful for chaining.
Example
// Simple event
Taplytics.track("Clicked Button");
// Event with value (revenue)
Taplytics.track("Purchased", 180.50);
// Event with value (revenue) and extra attributes
Taplytics.track("Purchased", 180.50, {
product_id: 100,
product_name: "Shirt"
});
// Event just with attributes
Taplytics.track("Finished Tutorial", {
time_on_tutorial: 100
});
page
Usage: Taplytics.page([category], [name], [page_attributes])
Tracks a page view. This is called once automatically from the init function.
You can call it manually yourself to structure the page view events, as well as when you have a single page Javascript application that does its own routing.
Currently, we do not listen on window.History
state change events to do this automatically.
Aliases
This function can also be called as follows:
Taplytics.page([name], [page_attributes]);
Arguments
[category]
(string): Page Category (optional).[name]
(string): Page Name (optional).[page_attributes]
(Object): Page attributes object.
Returns
(Object): Returns the Taplytics object, useful for chaining.
Example
// Track a page view with no attributes
Taplytics.page();
// Track it by setting a name
Taplytics.page("Page Name");
// Track a page view with a category and a name
Taplytics.page("Product Listings", "Shirts");
// Track a page view with a name and attributes
Taplytics.page("Shirts Page", {
products_count: 150
});
// Track a page view with a name, a category, and attributes
Taplytics.page("Product Listings", "Shirts", {
products_count: 150
});
reset
Usage: Taplytics.reset()
Resets the user object and assumes the visitor is now anonymous. This can be used to deatach the visitor from the user that you had used identify on earlier in the session.
Returns
(Object): Returns the Taplytics object, useful for chaining.
Example
// Reset user
Taplytics.reset();
propertiesLoaded
Usage: Taplytics.propertiesLoaded([callback])
Calls the function provided when the SDK's properties have loaded from Taplytics's servers.
Arguments
[callback]
(function): function to callback when properties have loaded.
Example
Taplytics.propertiesLoaded(function() {
// properties have loaded
});
runningExperiments
Usage: Taplytics.runningExperiments(callback)
Calls the function provided with an Object containing the running experiments and variation names when the SDK's config has loaded from Taplytics's servers.
Arguments
callback
(function): function to callback with running experiments and variations. With the Object's keys as experiment names, and values as the variation name.
Example
Taplytics.runningExperiments(function(expAndVars) {
// For example:
// expAndVars = {
// "Experiment 1": "baseline",
// "Experiment 2": "Variation 1"
//};
});
variable
Usage: Taplytics.variable(name, defaultValue, [updatedBlock])
Creates a Taplytics Variable with values that are controlled by your running experiments.
Arguments
name
(string): Variable Name.defaultValue
(string/number/boolean): Variable's default value.[updatedBlock]
(function): Update block to be called when the Variable'svalue
is set (optional).
Returns
(TLVariable): Returns a Taplytics Variable, use value
to get the variable's value
Example
// Using a asynchronous variable with the updated block
Taplytics.variable("JS String", "default", function(value) {
console.log("JS String value: " + value);
});
// Using a synchronous variable
Taplytics.propertiesLoaded(function() {
var syncVar = Taplytics.variable("JS String", "default");
console.log("JS String Sync value: " + syncVar.value);
});
codeBlock
Usage: Taplytics.codeBlock(name, codeBlock)
Creates a Taplytics Code Block that will be run if enabled for the running experiment/variation through Taplytics website.
Arguments
name
(string): Variable Name.codeBlock
(function): Code Block to be called if enabled for the experiment's variation.
Example
Taplytics.codeBlock("JS CodeBlock", function() {
console.log("JS Code Block");
// run your code here
});
Cookies
Below you'll find the Cookies that Taplytics is setting for session tracking, bucketing and identification purposes.
Name | Description |
---|---|
_tl_auid | Taplytics App User identifier |
_tl_csid | Taplytics Cookie Session identifier |
_tl_duuid | Taplytics Device identifier |
_tl_sid | Taplytics Session identifier |
_tl_uid | Taplytics user_id |
_tl_config | Taplytics Cached Config |
tl_sopts_{ }_p_p_l_h | Page Conversion Goals - previous page href |
tl_sopts_{ }_p_p_l | Page Conversion Goals - previous page location |
tl_sopts_{ }_p_p_l_t | Page Conversion Goals - previous page title |
tl_sopts_{ }_p_p_v_d | Page Conversion Goals - previous page view date |
Enable the Visual Editor
Making visual edits on the web with Taplytics is super easy! Similar to mobile, once the visual web editor tool has been enabled it's as simple as hovering over the element you'd like to edit and making the change.
All you need to do to enable the visual web editing tool is provide a google email address and then download the Taplytics Chrome Web Extension. From there you'll be able to make edits directly from on your website.
Making Visual Edits
All edits are done on your actual website and are only launched to production once you've started the experiment.
Using the visual editor you are able to make most types of changes to any static element on your website, including copy, size, colour, font, and image changes.
Changes are applied to the CSS selectors on each page and will be applied to specific pages based on the URL path.
If you'd like changes to stick to additional pages there is an option to "Match on all URL's". Checking this box will ensure changes made on one page will carry over to the matching element on another page. Taplytics does this by matching both on the base URL and then looking for additional CSS selectors to carry the change over to additional pages.
Updated 10 days ago