Basic Usage

The updated analytics library is now a UMD module supporting three new styles of asynchronous loading (queue/array, universal/function, and AMD module). Most ways of loading the library allow choosing between a legacy, backwards compatible API (API v1), and a new API (API v2) which supports gathering additonal/custom metrics, 3rd party integrations, and tracking events that do not perform DOM manipulation.

Both API versions offer small quality-of-life enhancements like method chaining, easier setup with the new loader scripts, and easier integration with 1st party code via tracker.exec.

Using universal-style asynchronous loader

Minified:

window.LassoAnalyticsAPI = 2; // If opting into new analytics API
(function(t,r,a,c,k,e,d){t.LassoAnalyticsObject=k;t[k]=t[k]||function(){(t[k].q=t[k].q||[]).push(arguments);return t[k]},e=r.createElement(a),e.async=1;e.src=c;d=r.getElementsByTagName(a)[0];d.parentNode.insertBefore(e,d)})(window,document,'script','https://platform.lassocrm.com/wt/analytics.min.js','LassoAnalytics');

LassoAnalytics('setAccountId', 'my-account-id')('track', {category: 'pageView'})('patchRegistrationForms');

Unminified:

window.LassoAnalyticsAPI = 2; // If opting into new analytics API
(function(win,doc,scr,url,name,elem,parnt) {
    win.LassoAnalyticsObject=name;
    win[name]=win[name]||function() {
        (win[name].q=win[name].q||[]).push(arguments);
        return win[name];
    },
    elem=doc.createElement(scr),
    elem.async=1;
    elem.src=url;
    parnt=doc.getElementsByTagName(scr)[0];
    parnt.parentNode.insertBefore(elem, parnt);
})(window,document,'script','https://platform.lassocrm.com/wt/analytics.min.js','LassoAnalytics');

LassoAnalytics('setAccountId', 'my-account-id')('track', {category: 'pageView'})('patchRegistrationForms');

Strip .min from the url string's path for the unminified version of the library. The LassoAnalytics string can be also swapped to an alternate value to change the name under which the library is globally exposed.

Using queue-style asynchronous loader

Minified:

window.LassoAnalyticsAPI = 2; // If opting into new analytics API
(function(t,r,a,c,k,e,d){t.LassoAnalyticsObject=k;t[k]=t[k]||[];e=r.createElement(a),e.async=1;e.src=c;d=r.getElementsByTagName(a)[0];d.parentNode.insertBefore(e,d)})(window,document,'script','https://platform.lassocrm.com/wt/analytics.min.js','LassoAnalytics');

LassoAnalytics.push(
    ['setAccountId', 'my-account-id'],
    ['track', {category: 'pageView'}],
    ['patchRegistrationForms']
);

Unminified:

window.LassoAnalyticsAPI = 2; // If opting into new analytics API
(function(win,doc,scr,url,name,elem,parnt) {
    win.LassoAnalyticsObject=name;
    win[name]=win[name]||[];
    elem=doc.createElement(scr),
    elem.async=1;
    elem.src=url;
    parnt=doc.getElementsByTagName(scr)[0];
    parnt.parentNode.insertBefore(elem, parnt);
})(window,document,'script','https://platform.lassocrm.com/wt/analytics.min.js','LassoAnalytics');

LassoAnalytics.push(
    ['setAccountId', 'my-account-id'],
    ['track', {category: 'pageView'}],
    ['patchRegistrationForms']
);

Strip .min from the url string's path for the unminified version of the library. The LassoAnalytics string can be also swapped to an alternate value to change the name under which the library is globally exposed.

Using RequireJS (API v2 only)

require.config({paths: {'lasso-analytics': 'https://platform.lassocrm.com/wt/analytics.min'}});
require(['lasso-analytics'], function(LA) {
    LA('setAccountId', 'my-account-id');
    LA('pageView');
    LA('patchRegistrationForms');
});

Strip .min from the url string's path for the unminified version of the library. Note that if RequireJS is loaded when the analytics library initializes, the latter will not be exposed as a global, so it must be accessed via RequireJS.

Using legacy synchronous loader (deprecated)

<script>
  // If opting into new analytics API, this must be set before loading the library
  window.LassoAnalyticsAPI = 2;
</script>
<script src="https://platform.lassocrm.com/wt/analytics.min.js" type="text/javascript"></script>
<script type="text/javascript">
    var tracker = new LassoAnalytics('my-account-id');
    tracker.track({category: 'pageView'}).patchRegistrationForms();
</script>

Strip .min from the url string's path for the unminified version of the library.

Performing 1st-party integrations

Use the tracker.exec method to perform any logic linking Lasso's data from a loaded tracker to any independent systems like so:

LassoAnalytics('exec', function(tracker) {
    MyIntegration.setExternalId(tracker.getGuid());
})

Running multiple trackers

Do not rely on specifying global name as a means to separately, asynchronously load two copies of the library; they will both overwrite one global using the last name specified. Instead, maintain separate configurations by using RequireJS or exec to asynchronously construct a second instance like so (example using universal-style format):

// using RequireJS
require(['lasso-analytics'], function(LA) {
    var otherTracker = new LA('my-other-id');
    otherTracker.pageView();
});

// using exec
LassoAnalytics('exec', function(tracker) {
    var otherTracker = new LassoAnalytics('my-other-id');
    otherTracker.pageView();
});

Note however that accountId is the only value that may vary between trackers and cannot be specified when triggering a metrics event in API v2, so using multiple trackers should be very rarely useful.

LassoAnalytics API

However the analytics library is loaded, it provides a single entry point that simultaneously serves as multi-format control interface for a single default Tracker instance, as well as a constructor for additinal Tracker instances. If loaded in a form that exposes it as a global, that global is by default LassoAnalytics.

new LassoAnalytics(accountId) ⇒ tracker

Create a new Tracker instance. It is not normally necessary to do so, as a default instance is automatically created and used by the front control interfaces. Additional instances may be used to maintain separate configuration for independent sets of tracking information. Note however that persistent data (i.e. the visitor guid) will still be shared.

params:

  • optional string accountId: The value to use as account id

LassoAnalytics.push([method, argument], …) ⇒ LassoAnalytics

Add one or more operations to perform, in queue-style format. If the library is still asynchronously loading, they will be automatically deferred; otherwise, they are executed immediately (synchronously). All operations will be performed on the default tracker instance and in the order they were submitted.

See the Tracker API for the list of methods that may be invoked.

params:

  • repeating array operationN:
    • string method: The name of the method to invoke
    • optional mixed argument: An argument to pass to the method

LassoAnalytics(method, argument) ⇒ LassoAnalytics

Add an operation to perform, in direct universal-style format. If the library is still asynchronously loading, it will be automatically deferred; otherwise it is executed immediately (synchronously). All operations will be performed on the default tracker instance and in the order they were submitted.

See the Tracker API for the list of methods that may be invoked.

params:

  • string method: The name of the method to invoke
  • optional mixed argument: An argument to pass to the method

LassoAnalytics.guid: string

Read-only property exposing the current visitor's guid. Accessing this property can trigger initialization of tracking cookies.

LassoAnalytics.version: string

Read-only property exposing LassoAnalytics API version in use. Returns string in form 2.x if opting into the V2 Tracker API, else 1.x.

LassoAnalytics.log: array

All operations invoked through the main control interface will also be recorded in this log array for debugging purposes. Note that when asynchronously loading the library, this property will not be available until loading is complete. The log only contains record of method invocations that were successful.

V2 Tracker API

All operations are performed through this Tracker object. It is not normally necessary to construct one manually, as a default instance is automatically created and used by the front control interfaces. Additional instances may be used to maintain separate state for independent sets of tracking information. Note however that guid and visit frequency data will still be shared.

Opt into using the new tracker API version by setting window.LassoAnalyticsAPI = 2 before the loader runs.

tracker.guid: string

Read-only property exposing the current visitor's guid. Accessing this property can trigger initialization of tracking cookies.

tracker.version: string

Read-only property exposing LassoAnalytics API version in use. Returns version string in form 2.x.

tracker.pageId: string

Writable property holding the string that will be used as default pageId value for pageView events and label for custom events. Initial value derives from page title. Can also be set via tracker.setPageId(id).

It is recommended to set your own pageId if page titles are long or not unique.

tracker.setAccountId(id) ⇒ tracker

Set the id of the client account for which tracking data is being sent (default null). This id must be set to send a tracking beacon and can be set by passing an id into the Tracker constructor, using this method, or by including it as an option in tracker.track.

The current value is also exposed as writable property tracker.accountId;

params:

  • string id: The value to use as account id

tracker.setPageId(id) ⇒ tracker

Set the value of pageId that will be used as default pageId value for pageView events and label for custom events. Initial value derives from page title. It is recommended to set your own pageId if page titles are long or not unique.

The current/default value is also exposed as writable property tracker.pageId;

params:

  • string id: The value to use as pageId

tracker.getGuid() ⇒ string

Get the guid for the current visitor. Triggers initialization of tracking cookies.

The guid is also exposed as read-only property tracker.guid;

tracker.pageView(details) ⇒ tracker

Send a pageView event. Equivalent to calling tracker.event({category: "pageView"}).

params:

  • optional object details: Data customizations transmitted for this beacon only
    • string pageId: The value to send as page identifier (as event label)
    • string url: The value to send as page URL (as event strValue)

tracker.event(details) ⇒ tracker

Emit a tracking beacon tracking a new event. Also aliased as tracker.track(details).

Only one of strValue or intValue must be sent, and the latter will be interpretted as an integer.

params:

  • object details: Data customizations transmitted for this beacon only
    • required string category: Name of the type of event being tracked
    • optional string label: An identifier for the specific event (defaults to pageId)
    • optional string strValue/intValue: A value associated with the event

tracker.registerIntegration(origin) ⇒ tracker

Begin replying to queries from integrated services running in iframes and loaded from the specified origin. See Integrations section for more information.

params:

  • string origin: The fully qualified host to trust (i.e. protocol://domain:port)

tracker.patchRegistrationForms(fieldName) ⇒ tracker

Search the current page for forms and prepopulate any fields named fieldName with the guid associated to the current visitor.

params:

  • string fieldName: The name of the input field to prepopulate (default guid)

tracker.exec(operation) ⇒ tracker

Run a user-supplied function that will be passed this tracker instance. Useful for wiring integrations through the main control interface that must wait on asynchronous loading.

params:

  • function operation: The function to run with this tracker

(Legacy) V1 Tracker API

All operations are performed through this Tracker object. It is not normally necessary to construct one manually, as a default instance is automatically created and used by the front control interfaces. Additional instances may be used to maintain separate state for independent sets of tracking information. Note however that guid and visit frequency data will still be shared

tracker.init() ⇒ tracker

Legacy method. Exists only for backwards compatibility with existing tracker setups.

Any initialization work required is now performed lazily. For example, persistent parameters like the visitor's guid are not loaded or created until some method needing them is run. If saving cookies for a visitor is desired even though no tracking beacons are being sent, perform any operation that accesses the guid to establish one.

tracker.setAccountId(id) ⇒ tracker

Set the id of the client account for which tracking data is being sent (default null). This id must be set to send a tracking beacon and can be set by passing an id into the Tracker constructor, using this method, or by including it as an option in tracker.track.

params:

  • string id: The value to use as account id

tracker.setPageTitle(title) ⇒ tracker

Set the value of pageTitle that will be transmitted in tracking beacons (by default the actual page title). It is not normally necessary to set the title manually, but recommended if the actual page title is excessively long.

params:

  • string title: The value to send as page title

tracker.setTokenKey(key) ⇒ tracker

Set the tracker instance's token key (default ldstok). The token key is name of an optional url query parameter that will be automatically copied from the current page url into in any tracking beacons sent. The parameter is used to carry an encrypted payload with special extra instructions. Currently it is only used to update the tracking guid associated with a known existing registrant.

Do not change the token key at this time. Doing so also changes the name of the parameter transmitted, and alternate names will be ignored.

params:

  • string key: The query parameter name to use

tracker.setTrackingDomain(domain) ⇒ tracker

Set the domain to which tracking beacons will be transmitted (default //app.lassocrm.com). It should never be necessary to set this in production but may be useful for testing purposes.

The full url pinged will be in the form TRACKING_DOMAIN/_ldst.gif?QUERY_PARAMS.

params:

  • string domain: The domain to which tracking beacons should be sent

tracker.track(options) ⇒ tracker

Emit a tracking beacon.

Beacon is currently transmited via a tracking pixel loaded into a hidden div using id _ldstdiv. This is subject to change, with possible future changes to rely on DOM manipulation only via custom configuration or as a last resort. No div is created until the first tracking beacon is sent.

params:

  • optional object options: Data customizations transmitted for this beacon only
    • string hostname: Canonical hostname to substitute in current page url sent
    • string pageTitle: The value to send as page title
    • string accountId: The value to use as account id

tracker.getGuid() ⇒ string

Get the guid for the current visitor. Triggers initialization of tracking cookies.

tracker.patchRegistrationForms(fieldName) ⇒ tracker

Search the current page for forms and prepopulate any fields named fieldName with the guid associated to the current visitor.

params:

  • string fieldName: The name of the input field to prepopulate (default guid)

tracker.exec(operation) ⇒ tracker

Run a user-supplied function that will be passed this tracker instance. Useful for wiring integrations through the main control interface that must wait on asynchronous loading.

params:

  • function operation: The function to run with this tracker

3rd-Party Integrations (API v2 only)

Authorized 3rd-party systems that use embedded iframes in client websites can perform some basic querying of the LassoAnalytics library (API V2 only) running in the parent page. In order for this to work, the client's website must authorize the cross-domain communication using the API method registerIntegration and passing in the host serving up the iframe content (i.e. LassoAnalytics('registerIntegration', 'protocol://domain:port')).

Once authorized, the embedded iframe can perform queries using window.parent.postMessage('Lasso|REQUEST', '*'), where REQUEST is one of the following:

  • PING: ask the tracker just to respond—this should be polled first
  • GUID: get the guid Lasso assigned to the visitor in the parent window
  • AccountId: get the accountId assigned by Lasso to this client's domain

Any asynchronous reply will come in the form Lasso|REQUEST|RESPONSE and can be captured using window.addEventListener('message', ...).

Reliable Integration Messaging

There's no guarantee the analytics library in the parent page will be loaded and listening by the time an integration starts sending queries from an iframe. By polling first with PING, you can ensure reliable communication for all subsequent real queries.

The following basic polling, validation and parsing logic is recommended:

<script type="text/javascript">

    (function(receiver) {
        if(window.parent == window) {
            var failed = Promise.reject(new Error('Have no parent window'));
            return window.queryLasso = function(msg) { return failed; }
        }

        var
            pass,
            fail,
            query = function(msg) { window.parent.postMessage('Lasso|'+msg, '*'); },
            ready = new Promise(function(resolve, reject) { pass = resolve, fail = reject; }),
            ping = query.bind(null, 'PING'),
            polling = setInterval(ping, 100);

        ping();

        // give up polling after 5s
        setTimeout(function() {
            if(!polling) return;
            clearInterval(polling);
            fail(new Error('Unable to communicate with LassoAnalytics'));
        }, 5000);

        window.addEventListener('message', function validateResponse(msg) {
            if(typeof msg.data != 'string') return;

            var parts = msg.data.split('|'),
                namespace = parts[0],
                name = parts[1],
                value = parts[2];

            if(namespace != 'Lasso') return;
            if(polling) {
                pass();
                clearInterval(polling);
                polling = false;
            }

            if(name == 'PING') return;

            receiver(name, value);
        });

        window.queryLasso = function(msg) {
            return ready.then(query.bind(null, msg));
        }

    })(function receiveLassoValue(name, value) {
        // Use the incoming data here
        console.log('received', name, value);
    });

    queryLasso('GUID').then(function() {
        console.log('queried for guid');
    });

</script>