Dynamic Tracking: Setup and configuration
The standard Parse.ly tracking code is useful for most situations. However, there are times when you want more control over the behavior of this code. Perhaps you don’t want the code to trigger a pageview automatically. Or, you may want to trigger multiple page views, at different times, on the same page (not to be confused with single-page applications). In these cases, we recommend that you implement Dynamic Tracking:
- Infinite scroll
- Image carousels
- Sending custom events
- Tracking downloadable files
Overview
Here is a full example that we will then break into functional parts:
<script>
window.PARSELY = window.PARSELY || {
onload: function() {
// will be called once PARSELY tracking code is loaded
// bind pageview tracking for all "next" links.
// example event listener; set your own based
// on your site design
jQuery("a.next").on("click", function() {
var url = this.href,
urlref = location.href;
PARSELY.beacon.trackPageView({
url: url,
urlref: urlref,
js: 1
});
return true;
});
}
};
</script>
<!-- START Parse.ly Include -->
<!-- ...insert the parsely tracker code here... -->
<!-- END Parse.ly Include -->
Note
The dynamic tracking code must be placed before the standard Parsely tracking snippet.
The code above waits until the Parse.ly tracking code has finished loading, and then using jQuery attaches to all click events for links with class next
. On click, a request to the analytics server is sent. The url
of the tracking event is set to the link that was clicked, whereas the urlref
is set to the current URL (before the event is sent and before a page transition happens).
This preserves the “internal referrer” (page-to-page tracking) for Parse.ly, while still allowing you to load the next piece of content dynamically, without incurring the cost of a full page refresh.
Note that url
and urlref
values are required to be absolute paths. This means that relative paths are not accepted (e.g. "/article"
as opposed to "http://www.example.com/article"
); they must be full URLs. They should also resolve or redirect to an actual page on your site that has crawlable metadata (see Providing Metadata for Dynamic Content below).
The onload handler
Parse.ly’s tracker code loads asynchronously, so the only way to reliably interact with its API is to set a handler for an onload
event that the API exposes.
Define a PARSELY
object before the tracking code like this:
<script>
window.PARSELY = window.PARSELY || {
onload: function() {
console.log("Parse.ly code has loaded");
// add your event listeners here
}
};
</script>
<!-- START Parse.ly Include -->
<!-- ...insert the parse.ly tracker code here... -->
<!-- END Parse.ly Include -->
Adding an event listener
Find the appropriate selector and attach an event listener to use as the trigger for when to send the dynamic tracking call. You can use jQuery (as in the example below) or vanilla JavaScript with an addEventListener()
method.
The below example imagines a site that has an <a>
tag with a class value of next
(<a class="next" href="...">
) that will trigger when it is clicked. Your event listener will be different.
jQuery("a.next").on("click", function() {
var url = this.href,
urlref = location.href;
//dynamically send tracking call
return true;
});
Dynamically sending a tracking call
To send a tracking request to the analytics server use PARSELY.beacon.trackPageView
. It takes a single JavaScript object (dictionary) with keys and values that will be beaconed to Parse.ly’s servers.
Note that the function is available only after the tracker code has finished loading.
PARSELY.beacon.trackPageView({
url: url, // URL to be tracked
urlref: urlref, // Referring URL
js: 1 // flag indicating this is dynamic
});
We used this object to demonstrate how to Track Files.
Disabling on-load tracking
The default behavior of the tracking code is to report an event as soon as the script has finished loading. You can prevent the behavior, by setting PARSELY.autotrack
to false
before the include.
<script>
window.PARSELY = window.PARSELY || {
autotrack: false,
onload: function() {
// add event listeners or other dynamic tracking logic, such as:
// PARSELY.beacon.trackPageView({ ... })
}
};
</script>
<!-- START Parse.ly Include -->
<!-- ... as above ... -->
<!-- END Parse.ly Include -->
Subsequent events could then be tracked using dynamic tracking.
If your account supports engaged time tracking, heartbeat events will be sent on every page by default, even when PARSELY.autotrack
is set to false
. If you plan to use dynamic tracking for pageview events, this behavior ensures that the tracker captures the full engagement. But if you need to disable both pageviews and heartbeat events, additionally set PARSELY.config.heartbeat_should_honor_autotrack
to true
, as in the example below.
<script>
window.PARSELY = window.PARSELY || {
autotrack: false,
config: {
heartbeat_should_honor_autotrack: true
},
onload: function() {
// add event listeners or other dynamic tracking logic, such as:
// PARSELY.beacon.trackPageView({ ... })
}
};
</script>
<!-- START Parse.ly Include -->
<!-- ... as above ... -->
<!-- END Parse.ly Include -->
This option is only supported in tracker versions above 1.0.3. If you’re unsure of your tracker version, contact support@parsely.com
Providing Metadata for Dynamic Content
While you can fire pageviews dynamically, Parse.ly’s web crawler, which extracts your metadata, can’t execute JavaScript. It must be able to access the metadata tag from the results of a single GET request. That means your metadata has to be included directly in the page source.
To configure metadata for dynamic content, just make sure that any content loaded dynamically can also be accessed at a standalone, static URL. For example, perhaps you have an article http://example.com/article1
, and when a reader reaches the bottom of the page, you load a new article via infinite scroll, firing a pageview for http://example.com/article2
. Parse.ly’s crawler can pick up that new article’s metadata just fine, provided that http://example.com/article2
is publicly accessible, with the desired metadata included in the page source.
This also means that any URLs sent as part of a dynamic tracking call should resolve to a page on your site that hosts metadata as described above. In the case of a photo gallery that loads with qsargs, hash URLs, Javascript, or scroll, you can use a dedicated qsarg
in the URL that’s sent to Parse.ly (example: a photo gallery that takes place on example.com/base
would have /base?slide=1
, /base?slide=2
, etc.). The key here is to ensure that the canonical URL is always the same as it will be our source for the metadata on the page.
Sending custom events
Parse.ly instruments pageview
events by default. This helps us track views and visitors. We also instrument heartbeat
events for customers who have accounts with support for engaged time.
In addition, our video tracker instruments two events, videostart
and vheartbeat
. The former tracks video start events and video visitors, while the latter tracks engaged time while watching videos.
However, you can send other custom events to Parse.ly by changing the action
attribute in your dynamic tracking calls.
To guarantee you don’t use a Parse.ly reserved name, we recommend you prefix custom events with an underscore, e.g. _subscribe
to track an e-mail newsletter subscription event, or _share
to track a share button click event. Here is an example of tracking a custom social share event from your pages:
PARSELY.beacon.trackPageView({
url: url,
urlref: urlref,
action: "_share" // custom event type
});
These custom events will be ignored by Parse.ly’s dashboard and live APIs, but will be accessible to you via Parse.ly’s Raw Data Pipeline.
Sending custom data with events
Arbitrary data can be included in the trackPageView
call by including a data
attribute in the argument object. This could be used to track a custom per-page or per-user data, such as identifiers or internal web application data.
Note that the data
object cannot include the keys parsely_uuid
or parsely_site_uuid
. Again, we recommend you use a leading underscore to avoid collision with reserved Parse.ly names. So, for example, to track a custom “scroll” event that also includes the current scroll depth, you could send the following:
PARSELY.beacon.trackPageView({
url: url,
urlref: urlref,
action: "_scroll", // custom event type
data: {
_y: window.scrollY // custom event attribute
}
});
Again, this custom scroll event will be ignored by Parse.ly’s dashboard and APIs, but you can use it to do scroll depth calculations via Parse.ly’s Raw Data Pipeline. In that case, it would show up as events where action
is _scroll
and extra_data._y
is set to an integer in the JSON object of your raw records.
When debugging custom events, you can filter on that action name in the network tab of your browser development tools: _scroll
for the event above.
You can also use updateDefaults
to set persistent custom data that will be sent along with each event regardless of whether you’re using dynamic tracking.
window.PARSELY = window.PARSELY || {
onload: function() {
PARSELY.updateDefaults({data: {_y: window.scrollY}});
}
};
Calling updateDefaults
in onload
will cause the passed parameters to be sent with all pixel requests from the tracker, including the initial pageload, video and engagement events, and and dynamic tracking calls. Any default data
properties set this way can still be overridden in a PARSELY.beacon()
call. As above, fields nested in a data
object will appear in the Raw Data Pipeline as attributes on extra_data
.
Queueing events before onload
When loading the Parse.ly JavaScript tracker asynchronously (the default behavior), it is possible that you’ll want to track events before the tracker has finished loading. This situation can arise when using an infinite-scroll layout, for example.
To handle this situation, you can queue events that occur before PARSELY.onload
is called and flush that queue during onload
. The following example code demonstrates this technique.
var parselyPreload = {eventQueue: [], loaded: false};
// run this when you would fire an event
function fireParselyEvent() {
var event = {
url: location.href,
urlref: document.referrer,
js: 1
};
if (parselyPreload.loaded) {
PARSELY.beacon.trackPageView(event);
} else {
parselyPreload.eventQueue.push(event);
}
}
// when Parse.ly is done loading, flush the queue
window.PARSELY = window.PARSELY || {
autotrack: false,
onload: function() {
parselyPreload.loaded = true;
for (var i = 0; i < parselyPreload.eventQueue.length; i++) {
PARSELY.beacon.trackPageView(parselyPreload.eventQueue[i]);
}
}
};
Example use cases
The following examples are necessarily simplified for illustration purposes, and are not meant to be used as-is. Any dynamic tracking logic should be customized and tailored to your specific site.
Transforming non-standard campaign parameters to supported parameters
The Parse.ly dashboard can display detailed campaign data when you use supported parameters. If you’re already using non-supported parameters to track campaigns in other systems, it’s possible to re-format those before sending a Parse.ly pageview.
*Example: Convert src
parameters to utm_source
before sending a Parse.ly pageview (so the values will be collected under the “Campaign Source” in the dashboard):*
window.PARSELY = window.PARSELY || {
// disable automatic tracking
autotrack: false,
onload: function() {
// will be called once, when the tracker loads
function renameParams(rawUrl, oldParam, newParam) {
// modify or replace this function as necessary
// a regex replacement is sufficient in this scenario,
// but more complicated situations might require
// parsing parameters or further transforming their values
var re = new RegExp("(.*?[&?])(" + oldParam + ")(?==)")
return rawUrl.replace(re, "$1" + newParam);
}
// dynamically send a pageview with a modified url
window.PARSELY.beacon.trackPageView({
url: renameParams(location.href, "src", "utm_source"),
urlref: document.referrer,
js: 1
});
}
};
// insert the parsely tracker code here...
Using GTM
Built into the Parse.ly GTM tag template is the ability to configure a dynamic tracking tag. This allows you to leverage the tools of your GTM container to configure when you want to trigger the dynamic pageview.
You can use the GTM dynamic tracking tag even if you have implemented the Parse.ly tracker via another method (e.g. the WordPress plugin or hardcoded). You just need to ensure the PARSELY
object has been loaded before triggering the tag.
Last updated: August 15, 2024