Executing JavaScript using Snapshots

Overview

Snapshots are typically used by non-devs to capture additional metadata as an eventevent - Action users take on your site or in your app. Events are the basic building blocks of reports. property that’s not automatically captured by Heap. They can also be used by developers to trigger custom JavaScript on your website without capturing any event properties.

We can leverage Snapshots to trigger client-side APIs whenever an event is triggered. This doc covers use cases where Snapshots are used to trigger JavaScript without returning an event property.

For a general overview of how Snapshots work and use cases for non-devs, see the Snapshots guide in our Help Center. To set up a JavaScript Snapshot from the event definition page, click the Add Snapshot button and select to value of javascript in the drop-down.

📘

Since we’re not capturing any metadata with these use cases, the events with these Snapshots will not return any event properties for the Snapshot.

Use Cases

Find the Index Position of a Selected Element in a List

You may want to know the position of an element in a list or grid that users are selecting. Use this snapshot template to capture the index position of the element that has been selected.

🚧

The Javascript below will not work as-is since some of the selectors must be customized to correctly match your site. Do not copy/paste this as-is. This is for conceptual example purposes only.

Name: Tile Position
Javascript Snapshot:

(function() {
    var selector = 'li.h-full' // Replace this CSS! Selector must target all of the elements in the list
    var selected_element = event.target.closest(selector)
    var all_elements = document.querySelectorAll(selector)
    return Array.prototype.indexOf.call(all_elements, selected_element);
})()

Call APIs

Since Snapshots can trigger JavaScript on your page, Snapshots can be used to call third party APIs, including Heap’s API. As an example, the snippet below adds your users’ most current timezone as a property.

Name: Add timezone as user property

JavaScript Snapshot:

(function() { var tz = Intl.DateTimeFormat().resolvedOptions().timeZone; heap.addUserProperties({ "Timezone": tz }); })();

The Snapshot above is used to trigger Heap’s client-side user property API, and it doesn’t return any data for the Snapshot property. The “Add timezone as user property” name is used simply to let us know what the Snapshot does for this example.

Once captured, you can use this data in your analysis to understand how well your geographically targeted ads are performing.

Add Timezone as a Heap User Property

To further enrich your Heap user data, you can capture users’ timezones. The Snapshot below adds the user’s current timezone as a Heap user property by triggering Heap’s client-side [heap.addUserProperties()](https://developers.heap.io/reference#adduserproperties) API. You can have this attached to any eventevent - Action users take on your site or in your app. Events are the basic building blocks of reports. that triggers at least once for users, like a pageview.

JavaScript Snapshot:

(function() {
    var tz = Intl.DateTimeFormat().resolvedOptions().timeZone;
    heap.addUserProperties({
        "Timezone": tz
    });
})();

Capture User State (Tealium)

📘

This example is for customers using our Tealium integration.

This example captures the logged-in user state from a site using Tealium. Other common examples include page_type, site_section, or visitor_type. Use this type of data for high-level content analysis, or to understand how user state affects key behaviors.

Name: Logged In

JavaScript Snapshot

utag_data.customer_logged_in

Analyze Image Types

eCommerce companies often AB test their images. But how can you tell which type of photography converts best: a lifestyle action shot vs a standard product shot? This example captures the name of the image file when clicked. Assuming you have some semantic data in the title that denotes the shot type, you can use this data within a Defined Property to analyze the effectiveness of different image types.

Name: Image

JavaScript Snapshot:

$(event.target).attr('src').split('/').pop()

📘

This example requires jQuery to execute correctly.

Capture Page Load Time

🚧

We do not recommend using the Page Load Time Snapshot on a Single Page Application as navigation timing events do not update after changes to the History API.

It may be important for you to know how long it takes for your page to finish loading and how that affects user behavior. We are unable to capture page load time as an event property on a default pageview event because Heap captures a pageview event before the page finishes loading.

In this example you will be using Snapshots like a tag manager. When the page loads, we will wait until the relevant data is available, then send a track API call. Note that a Page load property will be created, but it will contain no data as the function does not return a value.

You want this to fire on every page, so attach this code to a "View Any Page" pageview event to trigger this JavaScript whenever a user views a page on your website. If you do not have such an event, define it as View page *.

Name: Page load

JavaScript Snapshot:

(function() {
  var interval = setInterval(sendTrack, 200);

  function sendTrack() {
    if (window.performance.getEntriesByType("navigation")[0].domComplete > 0) {
      var loadTime = Math.round(window.performance.getEntriesByType("navigation")[0].domComplete);
      heap.track('Page Load', {
        'Load Time': loadTime
      });
      clearInterval(interval);
    }
  }
})();

See how page load time affects your key funnels by starting your analysis with this event and grouping by load time!

📘

Navigation timing events do not update after changes to the History API. The above method will not work on Single Page Applications.

Check if Users Have Enabled Browser Push Notifications

On modern browsers, you can check how many of your users have enabled your browser push notifications. You can do something similar for checking location permissions if your app depends on it (not compatible with all browsers).

The Snapshot below adds whether the user has enabled push notifications or not as a Heap user property by triggering Heap’s client-side [heap.addUserProperties()](https://developers.heap.io/reference#adduserproperties) API.

navigator.permissions.query({
    name: 'notifications'
}).then(function(result) {
    heap.addUserProperties({
        "Notifications Permission": result.state
    });
})

Scroll Tracking

Capturing how far users scroll on your website is important to see if users are viewing all of the content on a page. The Snapshot below measures the full length of a page, and it captures a custom Scroll Depth event by triggering Heap’s client-side heap.track() API every time a user scrolls a 25% of the full length (25%, 50%, 75%, 100%).

📘

Scroll depth is calculated on the scroll location within the body element. If the content on your website is contained within a container element, then this Snapshot will not function as expected.

(function() {
    var quarters = 0;
    var scrollHeight, quarterHeight, scrollDistance, divisible, scrollPercent;
    document.addEventListener("scroll", function() {
        scrollHeight = document.documentElement.scrollHeight - window.innerHeight;
        quarterHeight = scrollHeight / 4;
        scrollDistance = window.pageYOffset || (document.documentElement || document.body.parentNode || document.body).scrollTop;
        divisible = Math.trunc(scrollDistance / quarterHeight);
        if (quarters < divisible && divisible !== Infinity) {
            scrollPercent = divisible * 25;
            heap.track('Scroll Depth', {
                percent: scrollPercent
            });
            quarters++;
        }
    });
}());

Capturing Data from the Data Layer

You can capture any additional pieces of data within your data layer object by calling for the piece of data within the JavaScript snippet.

As an example, let’s say your data layer object (called data) is set up so that {id:"123", name:"foo"}. You would capture the objects within this data layer per the examples below.

Capture ID

Capture Name

Disabling JavaScript Snapshots (Admins only)

Admins can disable JavaScript Snapshots by navigating to Account > Manage > Privacy & Security and clicking the JavaScript Snapshots toggle.