Skip to content

Commit

Permalink
viewability module formatting
Browse files Browse the repository at this point in the history
  • Loading branch information
bretg committed Jul 28, 2022
1 parent 114e6bc commit 212b449
Show file tree
Hide file tree
Showing 2 changed files with 73 additions and 29 deletions.
8 changes: 6 additions & 2 deletions dev-docs/modules/bidViewableIO.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,11 @@ This feature is not intended to be a perfect measure of viewability. It is howev
2. Only works on browsers that support or on sites that have [polyfilled the IntersectionObserver API](https://github.com/w3c/IntersectionObserver/tree/main/polyfill)
3. Results can only be trusted if both the publisher and winning bidder are assumed to be acting in good faith.

Note that there are other viewability modules in Prebid.js:
- [Generic Viewability](/dev-docs/modules/viewability.html)
- [Bid Viewability - GAM](/dev-docs/modules/bidViewable.html)
- [Browsi Viewability](/dev-docs/modules/browsiRtdProvider.html)

## Configuration

{: .table .table-bordered .table-striped }
Expand All @@ -62,5 +67,4 @@ This feature is not intended to be a perfect measure of viewability. It is howev

## Related Reading

- [Building a PBJS analytics adapter](/dev-docs/integrate-with-the-prebid-analytics-api.html)
- [Building a PBJS bidder adapter](/dev-docs/bidder-adaptor.html)
- Alternate module: [Generic Viewability](/dev-docs/modules/viewability.html)
94 changes: 67 additions & 27 deletions dev-docs/modules/viewability.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,56 +17,93 @@ sidebarType: 1

## Overview


This module will trigger a viewability pixel when a given HTML element becomes viewable according to custom viewability criteria.

Notes:
- Does not depend on publishers using GAM ad server (does not use GPT's ImpressionViewableEvent).
Features:
- Does not depend on publishers using GAM ad server (i.e. does not use GPT's ImpressionViewableEvent).
- Enables custom viewability criteria (timeInView and inViewThreshold).
- Aims to provide (and in some ways extend) functionality of https://github.com/InteractiveAdvertisingBureau/openvv-html , but keeping the size to the bare minimun (openvv-html is ~26kb in size).
- Enables publishers to track viewability through callbacks or img/js pixels.
- Supports all mediatypes.
- Enables buy side to track viewability by posting a message from within the creative iframe (including the postMessage call in the ad markup), thus avoiding custom viewability scripts.

{: .alert.alert-warning :}
This module does not work on IE (uses IntersectionObserver).
This module does not work on IE because it uses the IntersectionObserver.

Note that there are other viewability modules in Prebid.js:
- [Bid Viewability - Ad Server Independent](/dev-docs/modules/bidViewableIO.html)
- [Bid Viewability - GAM](/dev-docs/modules/bidViewable.html)
- [Browsi Viewability](/dev-docs/modules/browsiRtdProvider.html)

## Usage

The viewability module provides two functions: `startMeasurement` and `stopMeasurement` which can be used to enable viewability measurements.
These functions are intended to be added to the page. Here's how they work:

1. startMeasurement creates a browser [IntersectionObserver](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API) which triggers when the defined div is in view according to the defined criteria.
2. When the criteria is met, the IntersectionObserver is cancelled and the supplied tracking URL is hit (as an image or iframe) or the supplied callback function is called.
3. If for any reason the viewability measurement should be stopped (e.g. a slide show changed the contents), the stopMeasurement function can be used.

## Configuration
### startMeasurement

Module does not need any configuration, as long as you include it in your PBJS bundle.
Viewability module has only two functions `startMeasurement` and `stopMeasurement` which can be used to enable more complex viewability measurements. Since it allows tracking from within creative (possibly inside a safe frame) this module registers a message listener, for messages with a format that is described bellow.
This function has 4 positional parameters when called as a function: `pbjs.viewability.startMeasurement(vid, element, tracker, criteria)`:

`startMeasurement`
This function has 4 parameters when called directly with `pbjs.viewability.startMeasurement()`:
- vid: unique viewability identifier, used to reference particular tracker which can later be used to stop the measurement. It allows for multiple trackers, with different criteria to be registered for a given HTML element, independently. vid is not autogenerated by startMeasurement(), it needs to be provided by caller so that it doesn't have to be posted back to the source iframe (in case viewability is started from within the creative).
- element: reference to an HTML element that needs to be tracked.
- tracker: ViewabilityTracker is an object type with two properties, `method` ('img'|'js'|'callback') and `value` which can be an URL string for 'img' and 'js' trackers, or a function for 'callback' tracker. Example: `{ method: 'img', value: 'http://my.tracker/123' }`
- criteria: ViewabilityCriteria is an object type with two properties, `inViewThreshold` which is a number (0, 1.0] representing a percentage of viewable element we're aiming at, and `timeInView` which is a number of milliseconds that a given element needs to be in view continuously, above a threshold. Example: `{ inViewThreshold: 0.5, timeInView: 1000 }`
{: .table .table-bordered .table-striped }
| pos | param | scope | type | description | example |
|-----|-------|-------|------|-------------|---------|
| 1 | vid | required | string | unique viewability identifier, used to reference particular tracker which can later be used to stop the measurement. It allows for multiple trackers, with different criteria to be registered for a given HTML element, independently. vid is not autogenerated by startMeasurement(), it needs to be provided by caller so that it doesn't have to be posted back to the source iframe (in case viewability is started from within the creative). | 'test-div-1' |
| 2 | element | required | reference | reference to the HTML element that needs to be tracked. | test-div |
| 3 | tracker | required | object | an object type with two properties, `method` ('img','js','callback') and `value` which can be an URL string for 'img' and 'js' trackers, or a function for 'callback' tracker. | `{ method: 'img', value: 'http://my.tracker/123' }` |
| 4 | criteria | required | object | an object type with two properties, `inViewThreshold` which is a number (0, 1.0] representing a percentage of viewable element we're aiming at, and `timeInView` which is a number of milliseconds that a given element needs to be in view continuously, above a threshold. | `{ inViewThreshold: 0.5, timeInView: 1000 }` |

When a tracker needs to be started, without direct access to pbjs, postMessage mechanism can be used to invoke `startMeasurement`, with a following payload: `vid`, `tracker` and `criteria` as described above, but also with `message: 'Prebid Viewability'` and `action: 'startMeasurement'`. Optionally payload can provide `elementId`, if available at that time (for ad servers where name of the iframe is known, or adservers that render outside an iframe). If `elementId` is not provided, viewability module will try to find the iframe that corresponds to the message source.
When a tracker needs to be started without direct access to Prebid.js, postMessage mechanism can be used to invoke `startMeasurement` with the following payload:

{: .table .table-bordered .table-striped }
| param | scope | type | description | example |
|-------|-------|------|-------------|---------|
| vid | required | string | unique viewability identifier. See the description above. | 'test-div-1' |
| tracker | required | object | see above | `{ method: 'img', value: 'http://my.tracker/123' }` |
| criteria | required | object | see above | `{ inViewThreshold: 0.5, timeInView: 1000 }` |
| message | required | string | must be 'Prebid Viewability' | 'Prebid Viewability' |
| action | required | string | must be 'startMeasurement' | 'startMeasurement' |
| elementId | optional | string | element ID. The message listener can figure this out from the source iframe. | 'test-div' |

`stopMeasurement`:
This function has only 1 parementer when called directly with `pbjs.viewability.stopMeasurement()`:
- vid: unique viewability identifier, referencing an already started viewability tracker.
### stopMeasurement

When a tracker needs to be stopped, without direct access to pbjs, postMessage mechanism can be used here as well, to invoke `stopMeasurement`, providing payload with `vid`, `message: 'Prebid Viewability'` and `action: 'stopMeasurement`.
This function has only 1 parementer when called as a function: `pbjs.viewability.stopMeasurement()`:

## Example of starting a viewability measurement, when you have direct access to pbjs
{: .table .table-bordered .table-striped }
| pos | param | scope | type | description | example |
|-----|-------|-------|------|-------------|---------|
| 1 | vid | required | string | the unique viewability identifier, referencing an already started viewability tracker. | 'test-div-1' |

When a tracker needs to be stopped without direct access to Prebid.js, postMessage mechanism can be used here as well to invoke `stopMeasurement`, providing payload with these fields:

{: .table .table-bordered .table-striped }
| param | scope | type | description | example |
|-------|-------|------|-------------|---------|
| vid | required | string | unique viewability identifier. See the description above. | 'test-div-1' |
| message | required | string | must be 'Prebid Viewability' | 'Prebid Viewability' |
| action | required | string | must be 'stopMeasurement' | 'stopMeasurement' |

## Examples

### Starting a viewability measurement when you have direct access to Prebid.js
{% highlight js %}

pbjs.viewability.startMeasurement(
'ae0f9',
document.getElementById('test_div'),
'test-div-1',
document.getElementById('test-div'),
{ method: 'img', value: 'http://my.tracker/123' },
{ inViewThreshold: 0.5, timeInView: 1000 }
);

{% endhighlight %}

## Example of starting a viewability measurement from within a rendered creative
### Starting a viewability measurement from within a rendered creative
{% highlight js %}

let viewabilityRecord = {
let viewabilityRecord = {
vid: 'ae0f9',
tracker: { method: 'img', value: 'http://my.tracker/123'},
criteria: { inViewThreshold: 0.5, timeInView: 1000 },
Expand All @@ -78,17 +115,17 @@ When a tracker needs to be stopped, without direct access to pbjs, postMessage m

{% endhighlight %}

## Example of stopping the viewability measurement, when you have direct access to pbjs
### Stopping the viewability measurement when you have direct access to Prebid.js
{% highlight js %}

pbjs.viewability.stopMeasurement('ae0f9');
pbjs.viewability.stopMeasurement('test-div-1');

{% endhighlight %}

## Example of stopping the viewability measurement from within a rendered creative
### Stopping the viewability measurement from within a rendered creative
{% highlight js %}

let viewabilityRecord = {
let viewabilityRecord = {
vid: 'ae0f9',
message: 'Prebid Viewability',
action: 'stopMeasurement'
Expand All @@ -97,3 +134,6 @@ When a tracker needs to be stopped, without direct access to pbjs, postMessage m
window.parent.postMessage(JSON.stringify(viewabilityRecord), '*');

{% endhighlight %}

## Related Reading
- Alternate module: [Bid Viewability - Ad Server Independent](/dev-docs/modules/bidViewableIO.html)

0 comments on commit 212b449

Please sign in to comment.