npm package: @immutabl3/universal-analytics
Description: A node module for Google's Universal Analytics tracking
Author: Jörg Tillmann
Latest version: 0.3.1

universal-analytics

=======

Setting up a new property in Google Analytics? follow these instructions to get your UA-xxxx code.    
https://support.google.com/analytics/answer/9304153#UA


A node module for Google's [Universal Analytics](http://support.google.com/analytics/bin/answer.py?hl=en&hlrm=de&answer=2790010) tracking via the [Measurement Protocol](https://developers.google.com/analytics/devguides/collection/protocol/v1/).

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](https://badge.fury.io/js/universal-analytics.svg)](https://www.npmjs.com/package/universal-analytics) [![Build Status](https://travis-ci.org/peaksandpies/universal-analytics.png?branch=master)](https://travis-ci.org/peaksandpies/universal-analytics)


# Table of Contents

- [Getting started](#getting-started)
- [Tracking](#tracking)
  - [Pageviews](#pageview-tracking)
  - [Screenviews](#screenview-tracking)
  - [Events](#event-tracking)
  - [Exceptions](#exception-tracking)
  - [User timings](#user-timing-tracking)
  - [Transactions](#transaction-tracking)
    - [Transaction items](#transaction-item-tracking)
- [Daisy-chaining tracking calls](#daisy-chaining-tracking-calls)
- [Setting persistent parameters](#setting-persistent-parameters)
- [Filter application tracking data](#filter-application-tracking-data)
- [Session-based identification](#session-based-identification)
- [Debug mode](#debug-mode)
- [Request Options](#request-options)
- [Shortcuts](#shortcuts)
- [Tests](#tests)


# Getting started

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

```
$ npm install universal-analytics
```

```javascript
import ua from 'universal-analytics'
```

Initialization expects at least your Google Analytics account ID:

```javascript
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](#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:

```javascript
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:
```javascript
const visitor = ua({
  id: 'UA-XXXX-XX', 
  uid: 'as8eknlll',
});
```
[see about User Id](https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters#uid)


Tracking a pageview without much else is now very simple:

```javascript
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.

# Tracking

## 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.

```javascript
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:

```javascript
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](AcceptableParams.md).

## Screenview tracking

Instead of pageviews app will want to track screenviews.

```javascript
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](AcceptableParams.md).

## Event tracking

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

```javascript
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:

```javascript
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()`:

```javascript
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](AcceptableParams.md).

## 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.

```javascript
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.
  .send()
```

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:

```javascript
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' })
  .send()
```

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](AcceptableParams.md).

## 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.

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

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

```javascript
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](AcceptableParams.md).

## 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.

```javascript
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](AcceptableParams.md).

# 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

```javascript
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#`:

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

# Filter application tracking data

Set a persistent parameter for [`Data Source`](https://developers.google.com/analytics/devguides/collection/protocol/v1/parameters#ds) to `app` in order to mark tracking data as `Application`.

```javascript
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](https://i.imgur.com/ZDZ3ZPO.png)

# 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.

```javascript
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:

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

# Tests

The tests are written with [moctapeha](https://github.com/substack/tape) and [Sinon.JS](https://github.com/cjohansen/Sinon.JS)

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

```
$ npm install
$ npm test
```