Javascript SDK

Overview

The MetaRouter Javascript SDK (or “Tag”) allows you to collect behavioral data on your website and stream it to your MetaRouter data infrastructure. It is based on the Segment’s open-sourced Analytics.js library, so if you are familiar with that library, you should notice many similarities between the two!

Analytics.js standardizes event collection. It provides mechanisms to collect just about any piece of behavioral data from your website. When combined with the Sync Injector, you can use the MetaRouter Tag to replace many of the javascript tags that are likely installed on your website, like the Google Gtag, Facebook Pixel, and many other tags offered by the vendors we integrate with.

Grabbing Your Tag’s Code Snippet

MetaRouter provides a code snippet that you can easily copy and paste into your website’s codebase.

  1. From the MetaRouter dashboard, select the Pipelines tab.
  2. Within a Pipeline card, hover over the three dot icon, and select the Build AJS File option. If you have not built a Pipeline yet, you will need to do so in order to grab your snippet.
  3. Build your AJS File. You can follow the File Builder doc for help with this process. Click the Save and Build button once you are finished.
  4. The next page will contain a snippet ready for you to install into your website’s codebase. Make sure you follow the Deploying Your AJS Tracking File doc to ensure that the snippet can appropriately call your AJS file to perform tracking. Alternatively, you may use the following snippet. You will need to insert your CDN URL and your pipeline's writeKey into the snippet manually.
<script type='text/javascript'>
!(function() {
  var analytics = (window.analytics = window.analytics || [])
  if (!analytics.initialize) {
    if (analytics.invoked) {
      window.console && console.error && console.error('Analytics.js snippet included twice.')
    } else {
      analytics.invoked = !0
      analytics.methods = [
        'trackSubmit',
        'trackClick',
        'trackLink',
        'trackForm',
        'pageview',
        'identify',
        'reset',
        'group',
        'track',
        'ready',
        'alias',
        'debug',
        'page',
        'once',
        'off',
        'on',
        'addSourceMiddleware',
        'addIntegrationMiddleware',
        'setAnonymousId',
        'addDestinationMiddleware',
      ]
      analytics.factory = function(e) {
        return function() {
          var t = Array.prototype.slice.call(arguments)
          t.unshift(e)
          analytics.push(t)
          return analytics
        }
      }
      for (var e = 0; e < analytics.methods.length; e++) {
        var key = analytics.methods[e]
        analytics[key] = analytics.factory(key)
      }
      analytics.load = function(key, e) {
        var t = document.createElement('script')
        t.type = 'text/javascript'
        t.async = !0
        t.src = ("https:"===document.location.protocol?"https://":"http://")+"YOUR_CDN_URL/path/to/file"+key+".js"
        var n = document.getElementsByTagName('script')[0]
        n.parentNode.insertBefore(t, n)
        analytics._loadOptions = e
      }
      analytics.SNIPPET_VERSION = '4.13.1'
      analytics.load("YOUR_writeKey")
      analytics.page()
    }
  }
})()
</script>

We do not recommend installation via a tag manager, but that may be done where absolutely necessary. Please let your Customer Success Manager know if you plan on deploying MetaRouter through a tag manager.

Installing Your Snippet

To install your snippet, simply add it within your website’s <head> tag, ideally above any other scripts or CSS code. It should always be included at the top of the header to ensure that the snippet initializes prior to any events being generated. If the tag is placed elsewhere within your website code, you will risk losing events that were fired prior to snippet initialization. The MetaRouter tag loads asynchronously, so it should not block loading of other website resources.

Generating Events

Now that your snippet is installed, you can begin collecting event data with MetaRouter! If you have not modified your snippet in any way, you will automatically begin collecting Page events, which are often required to be mapped to downstream vendors. Additionally, you can add Track events to begin collecting common or custom events, add Identify calls on pages where users can login or provide personal information to you, and add them to a Group via a Group call.

Utility Methods

The below Utility Methods will help you alter how Analytics.js loads on your browser:

Ready

The ready method ensures that Analytics.js has finished initializing prior to starting some other function. Once ready is emitted, the function within ready will execute. This may be helpful in specific situations, such as when another service may need to read the anonymousId that MetaRouter sets.

The ready method uses the following format:

analytics.ready(callback);

Load

The load method buffers the Analytics.js script’s initialization until a load call is made. This is helpful if you want to wait for some action or event to occur before the script loads. Ensure you only call load once.

export const analytics = new AnalyticsBrowser()

analytics.identify("example")

if (somethingHappens) {
    analytics.load({ writeKey: '<YOUR_WRITE_KEY>' }) // AJS initializes and enqueued events are flushed
}

The load method can also be used if you fetch settings asynchronously.

const analytics = new AnalyticsBrowser()
fetchWriteKey().then(writeKey => analytics.load({ writeKey }))

analytics.identify("example")

Timeout

The timeout method helps limit the run time of scripts included within callbacks and helper functions like trackLink and trackForm. The timeout is set in milliseconds. An example call below sets the timeout to 300 ms.

analytics.timeout(300);

Reset (Logout)

The reset method clears anonymousId, userId, and any traits associated with a currently identified user and/or group.

analytics.reset();

This method will not clear MetaRouter-set cookies, localStorage managed by MetaRouter, or values retrieved by the Sync Injector. Keep in mind that you will need to run analytics.reset() for each subdomain if you are utilizing multiple subdomains.

Keepalive

The Analytics.js files that MetaRouter provides contain a keepalive: true flag to ensure that event calls are not cancelled when a user navigates away from the current browser tab. This also allows MetaRouter to more accurately track session data gathered following a page unload or visibility change trigger. Event calls that are sent after a user navigates away from the browser tab will return with a status unknown.

Event Retries

Events may occasionally be sent unsuccessfully to MetaRouter. In these instances, events will be retried whenever Analytics.js encounters network or server errors. This primarily ensures that offline tracking can occur where internet connection is lost, or that data is not lost if the client temporarily cannot connect to your MetaRouter event ingestion API.

Analytics.js events will be stored in localStorage and fall back to in-memory storage if localStorage is unavailable. It will retry up to 10 times, and wait longer and longer between each retry. Up to 100 events may be queued at a time to prevent excessive usage of device memory.

Cross-Subdomain Tracking

Analytics.js automatically tracks users across subdomains. The anonymousId value is set on the top-level domain, so users will maintain a consistent anonymousId value across subdomains. This is true regardless of whether different snippets with different writekeys are implemented across those subdomains.

If you want to track users across top-level domains, see our Cross-Domain Tracking documentation.

UTM Tracking

Analytics.js will parse out UTM parameters anytime they are included in the page’s URL, making them available within your event payloads. These parameters will not be stored on the browser beyond the current session, as they are intended to be refreshed to prevent tracking inaccuracies.

Disable Client-side Persistence

You may disable the persistent storage of data Analytics.js sets client-side. This means that Analytics.js will only store data in-memory and will not automatically track identity across pages.

Use this function to disable client-side persistence:

analytics.load('analytics.js', {
   disableClientPersistence: true
})

Browser Compatibility

Analytics.js is compatible with the following browsers:

  • Internet Explorer (11 and later; prior version support cannot be guaranteed)
  • Apple Safari
  • Google Chrome
  • Mozilla Firefox
  • Microsoft Edge
  • Brave

Browser Tracking Restrictions

Browsers like Safari and Firefox enforce stronger tracking restrictions relating to first-party cookies that Analytics.js sets. Persistent cookie values like anonymousId may be stored on the browser for up to seven days prior to being purged. Use the HTTP Cookies setting to persist anonymousId beyond seven days in Safari and Firefox.

Single Page Applications

The default Page call made as a part of the standard MetaRouter tag snippet will not effectively pick up on new page “loads” within SPAs, as there are no new page loads that occur within SPAs. Instead, you will need to manually fire the [Page](https://docs.metarouter.io/docs/event-method-page) call when the route changes.

Updating the Referrer and URL

Analytics.js utilizes the value returned by document.referrer directly from the browser, and the URL represents the canonical URL on the page.

You may need to manually update the referrer and URL within your events to ensure that this URL is accurate when tracking within SPAs. To do this, set up a manual Page call:

analytics.page({
  referrer: 'https://example.com/referrer_example',
  url: 'https://example.com/other_url'
})

You may need to similarly manually update your Track calls to include the most accurate referral URL.

analytics.track('Example Event', {}, {page: {
  referrer: 'https://example.com/',
  url: 'https://example.com/other_url'
}})

Tracking Emulated Page Views

Even if you are emulating new page views by updating the URL in the address bar, new Page calls may not be fired as the resources are loaded on the initial page load. Therefore, instead of firing the Page call within your snippet, you should instead fire the Page call from the same logic that updates the view and URL path. You can do that with the following call:

analytics.page("example")

You can pass in more properties by including them within your call. Keep in mind that it is best to use variables for setting page properties instead of hardcoding those values. You may automate this by attaching the Page call to the routing service.

Managing Identity

AnonymousId

Analytics.js generates a unique UUID value for each new user during initialization and sets this as the user’s anonymousId.

When Is anonymousId Refreshed?

The anonymousId value is refreshed anytime one of the following occurs:

  • The user clears their cookies and local storage.
  • [analytics.reset()](https://docs.metarouter.io/docs/analyticsjs-for-web#reset-logout) is called during in the user’s browser session.
  • [analytics.identify()](https://docs.metarouter.io/docs/event-method-identify) is called with a userId that is different from the current userId.
  • The browser automatically clears cookie-based identifiers and storage.

Retrieving the AnonymousId

Use the following call to get the user’s current anonymousId:

analytics.user().anonymousId();

Persisting AnonymousId

The most common way that a user’s anonymousId value is refreshed is when their browser automatically deletes the anonymousId cookie. This is most common in Safari ITP, which places strict constraints on even first-party cookies. In order to extent the lifetime of the anonymousId cookie, which will in effect help you understand their behavior over time, you can activate tracking with HTTP cookies, which are not restricted in the same way that the standard javascript-set anonymousID value is.

Overriding the AnonymousId

It is possible to set the anonymousId value immediately within the Analytics.js snippet, even before the ready method returns. Use this call when you have queued calls before ready returns and they require access to the anonymousId value.

analytics.load('writekey');
analytics.page();
analytics.setAnonymousId('123-456-ABC');

You can also override the anonymousId with a call:

analytics.user().anonymousId('123-456-ABC');

Or:

analytics.setAnonymousId('123-456-ABC')

You can also override the anonymousId using the options object. This will become the default anonymousId value in subsequent calls even if this is not specified within those calls. You can use the following calls to do this:

Identify

analytics.identify('user_123', {
  name: 'John Doe'
}, {
  anonymousId: '123-456-ABC'
});

Track

analytics.track('Product Purchased', {
  price: 12.99
}, {
  anonymousId: '123-456-ABC'
});

Page

analytics.page({}, { anonymousId: '123-456-ABC' });

UserId

Saving Traits to the Context Object of Other Calls

Traits are like properties on most calls but describe what you know about a user or group, which can change over time. The context object provides a traits dictionary that can be used to describe a user. You can use traits to supplement the context object in future calls, giving you more information about the user to work with. See Identify documentation for more information.

Clearing Traits

You can clear any cached traits on a user by using these functions:

analytics.user().traits({});
analytics.group().traits({});

Return User & Group Information to the Console

Once the Analytics.js library has loaded, you can use the functions below to access cookie information and return information about the user or group currently identified.

User:

analytics.ready(function() {

  var user = analytics.user();
  var id = user.id();
  var traits = user.traits();

});

Group:

analytics.ready(function() {

  var group = analytics.group();
  var id = group.id();
  var traits = group.traits();

});

Anonymize IP Addresses

To prevent MetaRouter from being able to access IP addresses, you can anonymize it within your event code. We recommend that you simply not map it to your destinations, but you can also choose to anonymize IP addresses at the point of collection if you wish. Here’s an example of how you would do so:

analytics.track("Product Purchased", {}, { context: { ip: "0.0.0.0" }});

You will need to override IP address collection as shown here for every Track call you make.

Troubleshooting

In order to troubleshoot AJS, you will want to open your dev tools and navigate between various tabs to understand how the MetaRouter tag is loading on your website.

I’m not sure if Analytics.js is loading

Open your console, type analytics , and press enter. If you receive an error, then Analytics.js is not loading correctly.

Checking for events

When viewing a page where Analytics.js is installed, open your browser developer tools and navigate to the Network tab. Once the Network tab is open, refresh the page. You should see a p network call, which contains your Page event payload. If this is not being produced, and you are unable to trigger any other events (e.g. a t, i or g call) then Analytics.js is not functioning correctly. Reach out to your Customer Support Manager or contact us.

Event Payload Size Limit

Events will be accepted by MetaRouter up to 250kb. Any events larger than that will be rejected by MetaRouter, meaning the data will not be available to the platform or reach downstream vendors.

Additional Considerations

How can I enforce user consent on data collection?

Talk to your MetaRouter sales or support team about utilizing Advanced Consent Enforcement. You may also choose to handle when MetaRouter is loaded via your Consent Management Platform, if you use one.

What is the size of the Analytics.js library?

The Analytics.js library size is about 200kb when uncompressed. Each sync added by the Sync Injector will add an additional ~10kb.

Does Analytics.js track session data?

Yes, Analytics.js can track session data with the help of the Sync Injector. Specifically, you will need to use the MetaRouter Sync, which provides session tracking methodology to event payloads.

Can Analytics.js track scroll data?

Yes. If you need to track scroll data, please let our team know and we can provide logic to help track this within your event payloads.

Can I tag a website without access to my website code?

The only way that you can add the MetaRouter tag and track events without direct access your website’s code is by utilizing a tag manager to handle MetaRouter eventing. We do not recommend this pathway as it adds implementation and troubleshooting complexity. Please let the MetaRouter team know if you plan to implement any Analytics.js code via a tag manager.