blink
Library for user behaviour tracking.
Goals
The main goal is to make it easy to track user behavior on our sites.
- easy to configure
- fast
- small bundle size
- only collects and stores what is necessary
- ability to track multiple pages at the same time
Trackers
We have several types of trackers:
- Pageload tracking
- Active time tracking
- Impression tracking
- Ad tracking
- Click tracking
- Video tracking
- TCF consent change tracking
In addition, we expose one custom tracker type to fill miscellaneous needs.
Usage
import createBlink from '@aller/blink';
const blink = createBlink({
send: events => console.log(events),
sendDirect: events => console.log(events),
useDevTools: true,
});
blink.pageInit({
abCookie: 51,
commercialSegments: 'sport,soccer,gardening',
pageId: 'front-page',
pageType: 'instant-article',
referrer: 'www.dinside.no',
site: 'www.dagbladet.no',
url: 'http://dinside.no/a/93289234',
});
blink.pageLoad({
clientHeight: 600,
clientWidth: 800,
pageId: 'front-page',
plussData: { hasAccess: true, customerNumber: '123' },
scrollHeight: 34500,
url: 'http://dinside.no/a/93289234',
});
blink.performance({
domContentLoadedEventEnd: 100,
domContentLoadedEventStart: 50,
domInteractive: 200,
loadEventEnd: 40,
loadEventStart: 20,
responseEnd: 30,
responseStart: 10,
},
})
blink.webVitals({
CLS: {
value: 1.2,
attribution: "domelement"
},
TTFB: {
value: 123
},
LCP: {
value: 123,
attribution: "domelement"
},
INP: {
value: 123
},
FCP: {
value: 123
},
FID: {
value: 123
},
visitDurationAtSend: 1234
})
blink.consent({
uuid:"4f842ac4-50a1-40c7-bc8f-23a4373122f3_25",
tcfV2: "CP00b0AP00b0AAGABBENAYEgAAAAAEPAACgAAAANXgLgAIAAqAB4AEAAMgAaABzAD8AM0AfoBEQCLAEiAJSAXUA6QB5gD7QJkAmUBSYC8wGCANXADCgAQA5jwAQAcwDzFQAQAcwEygAA.YAAAAAAAAAAA",
kind: "gdpr",
consentGranted: true,
consentedToAll: false,
applies: false,
},
})
blink.click({
pageId: 'front-page',
url: 'http://seher.no/a/12931093',
context: [
'tag=a&i=1&n=1',
'tag=article&id=article_69676674&class=columns,large-8,medium-8,preview,small-12&dataId=69678379&i=1&n=1'
],
});
blink.adScreenEnter({ id: 'ad-topbanner' });
blink.adScreenExit({id: 'ad-topbanner' });
blink.adScreenEnter0({ id: 'ad-medium-rectangle' });
blink.adScreenExit0({id: 'ad-medium-rectangle' });
blink.adLoad({
id: 'ad-medium-rectangle',
offsetTop: 200,
offsetHeight: 450,
scrollTop: 100
});
blink.dfpImpressionViewable({
id: 'ad-medium-rectangle',
scrollTop: 100
});
blink.dfpSlotRenderEnded({
id: 'ad-medium-rectangle',
adUnitPath: '/8578/dagbladet.no/seksjoner/kjendis/artikkel',
advertiserId: 29318043,
campaignId: 123018391,
creativeId: 123908149018,
lineItemId: 344329408239,
prebidWinningBid: "30.49",
size: [300, 250]
sourceAgnosticCreativeId: 123908149018,
sourceAgnosticLineItemId: 344329408239,
scrollTop: 100,
});
blink.dfpSlotOnload({
id: 'ad-medium-rectangle1',
name: 'medium-rectangle1',
scrollTop: 100,
});
blink.articlePreviewScreenEnter({
context: ['tag=a&i=1&n=1', 'tag=article&i=1&n=1'],
height: 380,
personalizationParametersRequested: 'xavier-pluss',
personalizationSystemUsed: 'cerebro',
position: 5,
title: 'Surprising title!',
url: 'http://seher.no/kjendis/surprising-title/123980243',
width: 400,
});
blink.pageActivityStart({
url: 'http://seher.no/kjendis/surprising-title/123980243', pageScrollOffsetY: 493
});
blink.pageActivityStop({
url: 'http://seher.no/kjendis/surprising-title/123980243'
});
API
Page tracking
Should be called on a page initialization. Sets the pageView and computes values
that will not change over the course of the page view.
pageInit({
abCookie: number,
commercialSegments: string,
pageId: string,
pageType: string,
pageView: string,
previousPageView: string,
referrer: string,
site: string,
url: string,
});
Pageload
pageLoad({
clientHeight: number,
clientWidth: number,
pageId: string,
plussData: {
hasAccess: boolean,
customerNumber: string,
},
performance: {
domContentLoadedEventEnd: number,
domContentLoadedEventStart: number,
domInteractive: number,
domLoading: number,
loadEventEnd: number,
loadEventStart: number,
responseEnd: number,
responseStart: number,
},
scrollHeight: number,
url: string,
});
Screen tracking
screenShow({
time?: Date;
})
screenHide({
time?: Date;
})
Clicks
interface ClickInput {
id?: string;
url?: string;
context?: string[];
pageId?: string;
}
click(input: ClickInput): void;
Ads
adScreenEnter({ id: string; pageId?: string; time?: Date });
adScreenExit({ id: string; pageId?: string; time?: Date });
adScreenEnter0({ id: string; pageId?: string; time?: Date });
adScreenExit0({ id: string; pageId?: string; time?: Date };
adLoad({
id: string;
offsetHeight: number;
offsetTop: number;
scrollTop: number;
};
dfpImpressionViewable({
id: string;
scrollTop: number;
time?: Date;
});
dfpSlotRenderEnded({
adUnitPath: string;
advertiserId: number;
bidder: string;
campaignId: number;
creativeId: number;
id: string;
lineItemId: number;
prebidWinningBid: string;
scrollTop: number;
size: number[];
sourceAgnosticCreativeId: number;
sourceAgnosticLineItemId: number;
});
dfpSlotOnload({
id: string;
name: string;
scrollTop: number;
time?: Date;
});
Impression
articlePreviewScreenEnter({
context?: string[];
height?: number;
pageId?: string;
personalizationSystemUsed?: string;
personalizationParametersRequested?: string;
position?: number;
time?: Date;
title: string;
url: string;
width?: number;
});
Active Time
pageActivityStart({
url: string;
pageId?: string;
pageScrollOffsetY?: number;
time?: Date;
});
pageActivityStop({
url: string;
pageId?: string;
time?: Date;
});
Video
videoLoad({
videoId: string;
duration: number;
position: number;
title?: string;
width: number;
height: number;
viewable: boolean;
muted: boolean;
quality?: string;
withAdBlock: boolean;
time?: Date;
canBeSticky: boolean;
})
videoPlay({
videoId: string;
playerId: string;
time?: Date;
pageId?: string;
muted: boolean;
volume: number;
position: number;
reason: 'autostart' | 'interaction' | 'related-auto';
});
videoStop({
videoId: string;
playerId: string;
time?: Date;
pageId?: string;
muted: boolean;
volume: number;
position: number;
reason: 'pause' | 'complete' | 'exit';
beforeunload: boolean;
});
videoAd({
videoId: string;
playerId: string;
time?: Date;
pageId?: string;
adPosition: 'pre' | 'mid' | 'post';
system?: string;
title?: string;
client?: string;
viewable?: number;
adId?: string;
isBumper?: boolean;
creativeId?: string;
dealId?: string;
duration?: number;
});
Player
playerShown({
time: Date;
muted: boolean;
position: number;
volume: number;
sticky?: boolean;
playerId: string;
reason: 'viewable' | 'tabactive';
pageId?: string;
});
playerHidden({
time: Date;
muted: boolean;
position: number;
volume: number;
sticky?: boolean;
playerId: string;
reason: 'viewable' | 'tabclose' | 'tabhide';
pageId?: string;
});
playerSticky({
videoId: string;
playerId: string;
time?: Date;
pageId?: string;
sticky: boolean;
closed?: boolean;
})
Sending
Explicitly tell blink to send all events. A common usecase is to send all events
before a page is unloading.
sendAllEvents(time?: Date)
Box
Box tracking is for tracking elements on ap age that not neccesarily are article
previews, but more general boxes.
boxScreenEnter({
id: string;
title?: string;
height?: number;
width?: number;
pageId?: string;
time?: Date;
})
TCF Consent
consent({
uuid: string;
tcfV2: string;
kind: string;
consentGranted: boolean;
consentedToAll: boolean;
applies: boolean;
})
Custom
custom({
customDomain: string;
customType: string;
customContent?: string;
customValue?: number;
pageId?: string;
time?: Date;
});