# Track data out-of-the-box with the web trackers
> Track page views, structured events, and self-describing events with automatic context entities and custom timestamps using the web trackers.
> Source: https://docs.snowplow.io/docs/sources/web-trackers/tracking-events/
> Documentation index: https://docs.snowplow.io/llms.txt

To track an event, the API is slightly different depending if you're using the JavaScript or Browser version of our web tracker.

The main built-in events are [page views](/docs/sources/web-trackers/tracking-events/page-views/) and [page pings](/docs/sources/web-trackers/tracking-events/activity-page-pings/). Here's how to track them:

**JavaScript (tag):**

```javascript
<script type="text/javascript">
;(function(p,l,o,w,i,n,g){if(!p[i]){p.GlobalSnowplowNamespace=p.GlobalSnowplowNamespace||[];
p.GlobalSnowplowNamespace.push(i);p[i]=function(){(p[i].q=p[i].q||[]).push(arguments)
};p[i].q=p[i].q||[];n=l.createElement(o);g=l.getElementsByTagName(o)[0];n.async=1;
n.src=w;g.parentNode.insertBefore(n,g)}}(window,document,"script","{{URL to sp.js}}","snowplow"));

snowplow('newTracker', 'sp', '{{collector_url_here}}', {
    appId: 'my-app-id',
});

snowplow('enableActivityTracking', {
  minimumVisitLength: 30,
  heartbeatDelay: 10
});

snowplow('trackPageView');
</script>
```

**Browser (npm):**

```javascript
import {
  newTracker,
  trackPageView,
  enableActivityTracking
} from '@snowplow/browser-tracker';

newTracker('sp', '{{collector_url_here}}', {
    appId: 'my-app-id',
});

enableActivityTracking({
  minimumVisitLength: 30,
  heartbeatDelay: 10
});

trackPageView();
```

***

As well as page views and activity tracking, you can track [custom events](/docs/sources/web-trackers/custom-tracking-using-schemas/), or use [plugins](/docs/sources/web-trackers/plugins/) to track a wide range of other events and entities.

## Add contextual data with entities

The tracker can be set up to automatically add [entities](/docs/fundamentals/entities/) to every event sent.

Most entity autotracking is specifically configured using plugins, which are imported, enabled, and configured individually. However, you can configure some entities directly when instrumenting the tracker, using the [configuration object](/docs/sources/web-trackers/tracker-setup/initialization-options/).

| Entity                                                                                               | Usage                            | Added by default | JavaScript (tag) tracker | Browser (npm) tracker |
| ---------------------------------------------------------------------------------------------------- | -------------------------------- | ---------------- | ------------------------ | --------------------- |
| [`webPage`](/docs/sources/web-trackers/tracking-events/page-views/#page-view-id-and-web_page-entity) | UUID for the page view           | ✅                | `contexts` config        | `contexts` config     |
| [`session`](/docs/sources/web-trackers/tracking-events/session/)                                     | Data about the current session   | ❌                | `contexts` config        | `contexts` config     |
| [`browser`](/docs/sources/web-trackers/tracking-events/browsers/)                                    | Properties of the user's browser | ❌                | `contexts` config        | `contexts` config     |
| [`performanceTiming`](/docs/sources/web-trackers/tracking-events/timings/)                           | Performance timing metrics       | ❌                | `contexts` config        | Plugin                |
| [`gaCookies`](/docs/sources/web-trackers/tracking-events/ga-cookies/)                                | Extract GA cookie values         | ❌                | `contexts` config        | Plugin                |
| [`geolocation`](/docs/sources/web-trackers/tracking-events/timezone-geolocation/)                    | User's geolocation               | ❌                | `contexts` config        | Plugin                |

If you're using the `sp.lite.js` JavaScript tracker distribution, only the `webPage`, `session`, and `browser` entities are available out of the box, as the others require plugins that aren't included in that distribution.

You can also attach your own [custom entities](/docs/sources/web-trackers/custom-tracking-using-schemas/) to events.

For example, here is a page view with an additional custom entity:

**JavaScript (tag):**

```javascript
snowplow('trackPageView', {
  context: [{
    schema: "iglu:com.example_company/page/jsonschema/1-2-1",
    data: {
      pageType: 'test',
      lastUpdated: new Date(2021,04,01)
    }
  }]
});
```

**Browser (npm):**

```javascript
trackPageView({
  context: [{
    schema: 'iglu:com.example_company/page/jsonschema/1-2-1',
    data: {
      pageType: 'test',
      lastUpdated: new Date(2021,04,01)
    }
  }]
});
```

***

> **Note:** Tracker methods available through plugins do not necessarily support adding custom entities. For those please refer to the corresponding plugin documentation for details.

## Set event properties

Certain event properties, including `domain_userid` or `application_id`, can be set as [atomic properties](/docs/fundamentals/canonical-event/) in the raw event.

### Application ID

Set the application ID using the `appId` field of the [tracker configuration object](/docs/sources/web-trackers/tracker-setup/initialization-options/). This will be attached to every event the tracker fires. You can set different application IDs on different parts of your site. You can then distinguish events that occur on different applications by grouping results based on `application_id`.

### Application version

> **Info:** The option to track the application version was introduced in version 4.1 of the JavaScript tracker.

Set the application ID using the `appVersion` field of the [tracker configuration object](/docs/sources/web-trackers/tracker-setup/initialization-options/). This will be attached to every event the tracker fires using the [application entity](/docs/events/ootb-data/app-information/#entity-definitions).

The version of can be a semver-like structure (e.g 1.1.0) or a Git commit SHA hash.

### Application platform

Set the application platform using the `platform` field of the [tracker configuration object](/docs/sources/web-trackers/tracker-setup/initialization-options/). This will be attached to every event the tracker fires. Its default value is `web`. For a list of supported platforms, please see the [Snowplow Tracker Protocol](/docs/fundamentals/canonical-event/#application-fields).

### Business user ID

The JavaScript Tracker automatically sets a `domain_userid` based on a first party cookie. Read more about cookies [here](/docs/sources/web-trackers/cookies-and-local-storage/).

There are many situations, however, when you will want to identify a specific user using an ID generated by one of your business systems. To do this, you use one of the methods described in this section: `setUserId`, `setUserIdFromLocation`, `setUserIdFromReferrer`, and `setUserIdFromCookie`.

Typically, companies do this at points in the customer journey where users identify themselves e.g. if they log in.

> **Note:** This will only set the user ID on further events fired while the user is on this page; if you want events on another page to record this user ID too, you must call `setUserId` on the other page as well.

#### `setUserId`

`setUserId` is the simplest of the four methods. It sets the business user ID to a string of your choice:

**JavaScript (tag):**

```javascript
snowplow('setUserId', 'joe.blogs@email.com');
```

**Browser (npm):**

```javascript
setUserId('joe.blogs@email.com');
```

***

> **Note:** `setUserId` can also be called using the alias `identifyUser`.

#### `setUserIdFromLocation`

`setUserIdFromLocation` lets you set the user ID based on a querystring field of your choice. For example, if the URL is `http://www.mysite.com/home?id=user345`, then the following code would set the user ID to “user345”:

**JavaScript (tag):**

```javascript
snowplow('setUserIdFromLocation', 'id');
```

**Browser (npm):**

```javascript
setUserIdFromLocation('id');
```

***

#### `setUserIdFromReferrer`

`setUserIdFromReferrer` functions in the same way as `setUserIdFromLocation`, except that it uses the referrer querystring rather than the querystring of the current page.

**JavaScript (tag):**

```javascript
snowplow('setUserIdFromReferrer', 'id');
```

**Browser (npm):**

```javascript
setUserIdFromReferrer('id');
```

***

#### `setUserIdFromCookie`

Use `setUserIdFromCookie` to set the value of a cookie as the user ID. For example, if you have a cookie called “cookieid” whose value is “user123”, the following code would set the user ID to “user123”:

**JavaScript (tag):**

```javascript
snowplow('setUserIdFromCookie', 'cookieid');
```

**Browser (npm):**

```javascript
setUserIdFromCookie('cookieid');
```

***

### Custom page URL and referrer URL

The Snowplow JavaScript Tracker automatically tracks the page URL and referrer URL on any event tracked. However, in certain situations, you may want to override the one or both of these URLs with a custom value. For example, this might be desirable if your CMS spits out particularly ugly URLs that are hard to unpick at analysis time.

To set a custom page URL, use the `setCustomUrl` method:

**JavaScript (tag):**

```javascript
snowplow('setCustomUrl', 'http://mysite.com/checkout-page');
```

**Browser (npm):**

```javascript
setCustomUrl('http://mysite.com/checkout-page');
```

***

To set a custom referrer, use the `setReferrerUrl` method:

**JavaScript (tag):**

```javascript
snowplow('setReferrerUrl', 'http://custom-referrer.com');
```

**Browser (npm):**

```javascript
setReferrerUrl('http://custom-referrer.com');
```

***

> **Tip: For Single Page Apps**
>
> On an SPA, the page URL might change without the page being reloaded. Whenever an event is fired, the Tracker checks whether the page URL has changed since the last event. If it has, the page URL is updated and the URL at the time of the last event is used as the referrer. If you use `setCustomUrl`, the page URL will no longer be updated in this way. Similarly if you use `setReferrerUrl`, the referrer URL will no longer be updated in this way.
>
> To use `setCustomUrl` within an SPA, call it before all `trackPageView` calls.
>
> If you want to ensure that the original referrer is preserved even though your page URL can change without the page being reloaded, you have two options:
>
> **Declarative (recommended):** set `preserveOriginalReferrer: true` in the [tracker configuration](/docs/sources/web-trackers/tracker-setup/initialization-options/). The tracker automatically captures `document.referrer` at initialization and uses it as the referrer for all subsequent `trackPageView()` calls.
>
> **Imperative:** call `setReferrerUrl` with `document.referrer` before sending any events:
>
> **JavaScript (tag):**
>
> ```javascript
> snowplow('setReferrerUrl', document.referrer);
> ```
>
> **Browser (npm):**
>
> ```javascript
> setReferrerUrl(document.referrer);
> ```
>
> ***

### Custom timestamp

Snowplow events have several [timestamps](/docs/events/timestamps/).

Every `trackX...()` method in the tracker allows for a custom timestamp, called `trueTimestamp` to be set.

In certain circumstances you might want to set the timestamp yourself e.g. if the JS tracker is being used to process historical event data, rather than tracking the events live. In this case you can set the `true_timestamp` for the event.

To set the true timestamp add an extra argument to your track method: `{type: 'ttm', value: unixTimestampInMs}`.

This example shows how to set a true timestamp for a page view event:

**JavaScript (tag):**

```javascript
snowplow('trackPageView', {
  timestamp: { type: 'ttm', value: 1361553733371 }
});
```

**Browser (npm):**

```javascript
trackPageView({
  timestamp: { type: 'ttm', value: 1361553733371 }
});
```

***

E.g. to set a true timestamp for a self-describing event:

**JavaScript (tag):**

```javascript
snowplow('trackSelfDescribingEvent', {
  event: {
    schema: 'iglu:com.acme_company/viewed_product/jsonschema/2-0-0',
    data: {
        productId: 'ASO01043',
        category: 'Dresses',
        brand: 'ACME',
        returning: true,
        price: 49.95,
        sizes: ['xs', 's', 'l', 'xl', 'xxl'],
        availableSince: new Date(2013,3,7)
    }
  },
  timestamp: { type: 'ttm', value: 1361553733371 }
});
```

**Browser (npm):**

```javascript
trackSelfDescribingEvent({
  event: {
    schema: 'iglu:com.acme_company/viewed_product/jsonschema/2-0-0',
    data: {
        productId: 'ASO01043',
        category: 'Dresses',
        brand: 'ACME',
        returning: true,
        price: 49.95,
        sizes: ['xs', 's', 'l', 'xl', 'xxl'],
        availableSince: new Date(2013,3,7)
    }
  },
  timestamp: { type: 'ttm', value: 1361553733371 }
});
```

***

## Get event properties

It's possible to retrieve certain identifiers and properties for use in your code. You'll need to use a callback for the JavaScript tracker.

**JavaScript (tag):**

If you call `snowplow` with a function as the argument, the function will be executed when `sp.js` loads:

```javascript
snowplow(function () {
  console.log("sp.js has loaded");
});
```

Or equivalently:

```javascript
snowplow(function (x) {
  console.log(x);
}, "sp.js has loaded");
```

The callback you provide is executed as a method on the internal `trackerDictionary` object. You can access the `trackerDictionary` using `this`.

```javascript
// Configure a tracker instance named "sp"
snowplow('newTracker', 'sp', '{{COLLECTOR_URL}', {
 appId: 'snowplowExampleApp'
});

// Access the tracker instance inside a callback
snowplow(function () {
 var sp = this.sp;
 var domainUserId = sp.getDomainUserId();
 console.log(domainUserId);
})
```

The callback function shouldn't be a method:

```javascript
// TypeError: Illegal invocation
snowplow(console.log, "sp.js has loaded");
```

This won't work because the value of `this` in the `console.log` function will be the `trackerDictionary`, rather than `console`.

You can get around this problem using `Function.prototoype.bind` as follows:

```javascript
snowplow(console.log.bind(console), "sp.js has loaded");
```

For more on execution context in JavaScript, see the [MDN page](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this).

**Browser (npm):**

When initialising a tracker, you can use the returned `tracker` instance to access various properties from this tracker instance.

```javascript
// Configure a tracker instance named "sp"
const sp = newTracker('sp', '{{COLLECTOR_URL}', {
 appId: 'snowplowExampleApp'
});

// Access the tracker properties
const domainUserId = sp.getDomainUserId();
```

***

### Cookie values

You can [retrieve cookie values](/docs/sources/web-trackers/cookies-and-local-storage/getting-cookie-values/) using the `getDomainUserInfo` and other getters, or from the cookies directly.

### Page view ID

When the JavaScript Tracker loads on a page, it generates a new [page view UUID](/docs/sources/web-trackers/tracking-events/page-views/). To get this page view ID, use the `getPageViewId` method:

**JavaScript (tag):**

```javascript
// Access the tracker instance inside a callback
snowplow(function () {
 var sp = this.sp;
 var pageViewId = sp.getPageViewId();
 console.log(pageViewId);
})
```

**Browser (npm):**

```javascript
const pageViewId = sp.getPageViewId();
console.log(pageViewId);
```

***

### Business user ID

The `getUserId` method returns the user ID which you configured using `setUserId()`:

**JavaScript (tag):**

```javascript
// Access the tracker instance inside a callback
snowplow(function () {
 var sp = this.sp;
 var userId = sp.getUserId();
 console.log(userId);
})
```

**Browser (npm):**

```javascript
const userId = sp.getUserId();
console.log(userId);
```

***

### Tab ID

If you've enabled the [`browser` entity](/docs/sources/web-trackers/tracking-events/browsers/), you can get the tab ID using the `getTabId` method. It's a UUID identifier for the specific browser tab the event is sent from.

**JavaScript (tag):**

```javascript
// Access the tracker instance inside a callback
snowplow(function () {
 var sp = this.sp;
 var tabId = sp.getTabId();
 console.log(tabId);
})
```

**Browser (npm):**

```javascript
const tabId = sp.getTabId();
console.log(tabId);
```

***
