0.3.1 • Public • Published



Setting up a new property in Google Analytics? follow these instructions to get your UA-xxxx code.

A node module for Google's Universal Analytics tracking via the Measurement Protocol.

This module allows tracking data (or rather, users) from within a Node.js application. Tracking is initiated on the server side and, if required, does not require any more tracking in the browser.

npm version Build Status

Table of Contents

Getting started

universal-analytics is installed and included like any other node module:

$ npm install universal-analytics
import ua from 'universal-analytics'

Initialization expects at least your Google Analytics account ID:

const visitor = ua({ id: 'UA-XXXX-XX' });

This will create a universal-analytics Visitor instance that you can use and keep around to track a specific client (Not to be confused with the Google Analytics User id, see Setting persistent parameters for more information on that). Since no client ID was specified in the constructor's arguments, a random UUID is generated. In case you have a client ID at hand, you can use that to create the visitor:

const visitor = ua({
  id: 'UA-XXXX-XX',
  cid: '6a14abda-6b12-4578-bf66-43c754eaeda9',

Starting with Universal Analytics, a UUID v4 is the preferred client id format. It is therefor necessary to provide a UUID of such type to universal-analytics

If you want to set User Id you can add it into options:

const visitor = ua({
  id: 'UA-XXXX-XX', 
  uid: 'as8eknlll',

see about User Id

Tracking a pageview without much else is now very simple:

await visitor.pageview('/').send();

The first argument for the pageview method is the path of the page to be tracked. Simply calling pageview() will not initiate a tracking request. You can append a send() call after pageview(). The tracking request is sent asynchronously.


Pageview tracking

The first argument for the pageview tracking call is the page path. Furthermore, pageview tracking can be improved with the additional parameters to provide the page's hostname and title to Google Analytics. The parameters are provided as arguments after the page path.

await visitor.pageview('/', 'http://peaksandpies.com', 'Welcome').send();

Depending on how you integrate tracking into your app, you might be more comfortable with providing all the tracking data via a params object to the pageview() method:

await visitor.pageview({ dp: '/', dt: 'Welcome', dh: 'http://peaksandpies.com' }).send();

This code has the exact same effect as the one above. dp (document path), dt (document title), and dh ('document hostname') are the attribute names used by the Measurement Protocol.

It's mandatory to specify either the page path (dp) or document location (dl). Google Analytics can not track a pageview without a path. To avoid such erroneous requests, universal-analytics will deny pageview() tracking if the required parameters are omitted.

The following method signatures are available for the pageview() method of the Visitor instance:

  • Visitor#pageview(path)
  • Visitor#pageview(params)
  • Visitor#pageview(path, hostname)
  • Visitor#pageview(path, hostname, title)

See also: List of acceptable params.

Screenview tracking

Instead of pageviews app will want to track screenviews.

await visitor.screenview('Home Screen', 'App Name').send();

The following method signatures are available for #screenview:

  • Visitor#screenview(screenName, appName)
  • Visitor#screenview(screenName, appName, appVersion)
  • Visitor#screenview(screenName, appName, appVersion, appId)
  • Visitor#screenview(screenName, appName, appVersion, appId, appInstallerId)

See also: List of acceptable params.

Event tracking

Tracking events with universal-analytics works like pageview tracking, only you have to provide different arguments:

await visitor.event('Event Category', 'Event Action').send();

This is the most straightforward way to track an event. The event attributes label and value are optional and can be provided if necessary:

await visitor.event('Event Category', 'Event Action', '…and a label', 42).send();

Notice: The page path attribute for the event is called p which differs from the dp attribute used in the pageview tracking example. universal-analytics is smart enough to use the dp attribute should you provide it instead of p.

In case this argument list is getting a little long, event() also accepts a params object like pageview():

const params = {
  dp: '/contact',
  ec: 'Event Category',
  ea: 'Event Action',
  el: '…and a label',
  ev: 42,

await visitor.event(params).send();

The category (ec) and the action (ea) are mandatory. Google Analytics will not track an event without them. To avoid such erroneous requests, universal-analytics will deny event() tracking if either attribute is omitted.

The following method signatures are available for #event:

  • Visitor#event(category, action)
  • Visitor#event(category, action, label)
  • Visitor#event(category, action, label, value)

See also: List of acceptable params.

E-commerce tracking

E-commerce tracking in general is a bit more complex. It requires a combination of one call to the transaction() method and one or more calls to the item() method.

await visitor
  .transaction('trans-12345', 500)   // Create transaction trans-12345 worth 500 total.
  .item(300, 1, 'item-54321')        // Add 1 unit the item item-54321 worth 300.
  .item(200, 2, 'item-41325')        // Add 2 units the item item-41325 worth 200.

Once again, daisy-chaining simplifies associating the items with the transaction. Officially, nothing but the transaction id is a requirement for both the transaction and the items. However, providing a minimum set of information (revenue for the transaction, price, quantity and id for the items) is recommended.

It is also possible to provide the params as an object to both methods:

await visitor
  .transaction({ ti: 'trans-12345', tr: 500, ts: 50, tt: 100, ta: 'Partner 13' })
  .item({ ip: 300, iq: 1, ic: 'item-54321', in: 'Item 54321', iv: 'Blue' })
  .item({ ip: 200, iq: 2, ic: 'item-41325', in: 'Item 41325', iv: 'XXL' })

In case an additional item has to be added later on or daisy-chaining is not available for another reason, each item can be given an associated transaction ID via the params object as well:

The transaction id (ti) is mandatory for both the transaction and the item. Google Analytics will not track e-commerce data without it. To avoid such erroneous requests, universal-analytics will deny transaction() and item() tracking if it is omitted.

The following method signatures are available for #transaction:

  • Visitor#transaction(id)
  • Visitor#transaction(id, revenue)
  • Visitor#transaction(id, revenue, shipping)
  • Visitor#transaction(id, revenue, shipping, tax)
  • Visitor#transaction(id, revenue, shipping, tax, affiliation)

The following method signatures are available for #item:

  • Visitor#item(price)
  • Visitor#item(price, quantity)
  • Visitor#item(price, quantity, sku)
  • Visitor#item(price, quantity, sku, name)
  • Visitor#item(price, quantity, sku, name, variation)

See also: List of acceptable params.

Exception tracking

Exception tracking is a way to keep track of any sort of application errors and bugs with Google Analytics. Using it with this module is a way to capture server-side problems.

await visitor.exception('StackOverflow Error').send()

As an additional information, the exception can be flagged as fatal if the error was exceptionally bad.

const fatal = true;
await visitor.exception('StackOverflow Error', fatal);

The following method signatures are available for #exception:

  • Visitor#exception(description)
  • Visitor#exception(description, fatal)

See also: List of acceptable params.

User timing tracking

Tracking user timings is a way to capture time-based information similar to the page load speed data tracked automatically by Google Analytics. All arguments to this tracking method are optional, but a category, a variable and a time value should be provided. The time value should be provided in milliseconds.

await visitor.timing('User interaction', 'Time to open login overlay', 12547).send()

The following method signatures are available for #timing:

  • Visitor#timing(category)
  • Visitor#timing(category, variable)
  • Visitor#timing(category, variable, time)
  • Visitor#timing(category, variable, time, label)

See also: List of acceptable params.

Setting persistent parameters

Some parameters should be in every tracking call, such as a user ID or custom dimensions that never or hardly change. For such situations a #set(key, value) method is available

visitor.set('uid', '123456789');

The uid parameter will be part of every tracking request of that visitor from now on.

For custom dimensions, you will not pass dimension# rather cd#:

 visitor.set('cd[1-20]', '123456789'); // [1-20] will be the dimension number

Filter application tracking data

Set a persistent parameter for Data Source to app in order to mark tracking data as Application.

visitor.set('ds', 'app'); // Allows filtering by the 'Application?' field in GA

Then create a new view in Google Analytics of type 'Application'. You will then need to filter the data for that view by creating a new filter that either includes or excludes Application? Yes (depending on if you want to show(includes) or hide(excludes) application analytics in a given view).

Google Analytics Setup

Session-based identification

In order to make session-based apps easier to work with, universal-analytics also provides a middleware that works in an Expressjs-style fashion. It will try to detect a client ID based on the _ga cookie used by the analytics.js client-side tracking. Additionally it will store the detected client ID in the current session to recognize the visitor later.

import ua from 'universal-analytics';
import express from 'express';

const app = express();

express.use(ua.middleware('UA-XXXX-Y', { cookieName: '_ga' }));

The middleware will attach the universal analytics visitor instance to every request with the default name of req.visitor. The name of the instance on the req object can be overridden to avoid name conflicts by passing in instanceName on the options object:

express.use(ua.middleware('UA-XXXX-Y', { instanceName: 'uaVisitor' }));


The tests are written with moctapeha and Sinon.JS

Run them by executing the following commands in the universal-analytics directory:

$ npm install
$ npm test

Package Sidebar


npm i @immutabl3/universal-analytics

Weekly Downloads






Unpacked Size

69.7 kB

Total Files


Last publish


  • immutablellc