@financial-times/n-tracking
Advanced tools
Comparing version 1.0.0 to 1.1.0-beta.1
import oTracking from '@financial-times/o-tracking'; | ||
import oGrid from '@financial-times/o-grid'; | ||
import oViewport from '@financial-times/o-viewport'; | ||
import Perfume from 'perfume.js'; | ||
@@ -119,2 +120,110 @@ function getUserData () { | ||
/** | ||
* userIsInCohort | ||
* | ||
* @param {integer} cohortPercent the percentage of users you want in your cohort. | ||
* @returns {boolean} true if the user's spoor number is between zero and `cohortPercent`. | ||
*/ | ||
const userIsInCohort = cohortPercent => { | ||
if (!cohortPercent || isNaN(cohortPercent)) return false; | ||
const { cookie } = document || {}; | ||
if (!cookie) return false; | ||
let spoorNumber = false; | ||
let isInCohort = false; | ||
try { | ||
spoorNumber = parseInt(decodeURIComponent(cookie.match(/spoor-id=([^;]+)/)[1].replace(/[^0-9]+/g,''))); | ||
isInCohort = spoorNumber % 100 <= cohortPercent; | ||
} catch (error) { | ||
// The spoor id is not in the cohort percentile. | ||
} | ||
return isInCohort; | ||
}; | ||
// Perfume.js is a web performance package. | ||
// @see https://zizzamia.github.io/perfume/#/default-options/ | ||
const options = { | ||
logging: false, | ||
firstPaint: true, | ||
largestContentfulPaint: true, | ||
firstInputDelay: true, | ||
largestContentfulPaint: true, | ||
navigationTiming: true, | ||
}; | ||
// @see "Important metrics to measure" https://web.dev/metrics | ||
const requiredMetrics = [ | ||
'domInteractive', | ||
'domComplete', | ||
'timeToFirstByte', | ||
'firstPaint', | ||
'largestContentfulPaint', | ||
'firstInputDelay' | ||
]; | ||
const cohortPercent = 5; | ||
const realUserMonitoringForPerformance = () => { | ||
// Check browser support. | ||
// @see https://developer.mozilla.org/en-US/docs/Web/API/PerformanceLongTaskTiming | ||
if (!'PerformanceLongTaskTiming' in window) return; | ||
// Gather metrics for only a cohort of users. | ||
if (!userIsInCohort(cohortPercent)) return; | ||
const navigation = performance.getEntriesByType('navigation')[0]; | ||
const { type, domInteractive, domComplete } = navigation; | ||
// Proceed only if the page load event is a "navigate". | ||
// @see: https://developer.mozilla.org/en-US/docs/Web/API/PerformanceNavigationTiming/type | ||
if (type !== 'navigate') return; | ||
const context = { | ||
action: 'performance', | ||
category: 'page', | ||
domInteractive: Math.round(domInteractive), | ||
domComplete: Math.round(domComplete), | ||
}; | ||
/** | ||
* analyticsTracker() | ||
* | ||
* This function is called every time one of the performance events occurs. | ||
* The "final" event should be `firstInputDelay`, which is triggered by any "input" event (most likely to be a click.) | ||
* Once all the metrics are present, it fires a broadcast() to the Spoor API. | ||
*/ | ||
let hasAlreadyBroadcast = false; | ||
options.analyticsTracker = (({ metricName, duration, data }) => { | ||
if (hasAlreadyBroadcast) return; | ||
if (duration) { | ||
// Metrics with "duration": | ||
// firstPaint, firstContentfulPaint, firstInputDelay and largestContentfulPaint | ||
context[metricName] = Math.round(duration); | ||
} | ||
else if (metricName === 'navigationTiming') { | ||
context.timeToFirstByte = Math.round(data.timeToFirstByte); | ||
} | ||
// Broadcast only if all the metrics are present | ||
const contextContainsAllRequiredMetrics = requiredMetrics.every(metric => !isNaN(context[metric])); | ||
if (contextContainsAllRequiredMetrics) { | ||
console.log({performanceMetrics:context}); // eslint-disable-line no-console | ||
broadcast('oTracking.event', context); | ||
hasAlreadyBroadcast = true; | ||
} | ||
}); | ||
new Perfume(options); | ||
}; | ||
// TODO: implement and test trackers copied over from n-ui | ||
var index = /*#__PURE__*/Object.freeze({ | ||
__proto__: null, | ||
realUserMonitoringForPerformance: realUserMonitoringForPerformance | ||
}); | ||
const SPOOR_API_INGEST_URL = 'https://spoor-api.ft.com/ingest'; | ||
@@ -155,4 +264,3 @@ | ||
} | ||
// export * from './trackers'; | ||
export { SPOOR_API_INGEST_URL, broadcast, init }; | ||
export { SPOOR_API_INGEST_URL, broadcast, init, index as trackers }; |
@@ -6,3 +6,3 @@ { | ||
"browser": "dist/browser.js", | ||
"version": "1.0.0", | ||
"version": "1.1.0-beta.1", | ||
"license": "MIT", | ||
@@ -39,3 +39,4 @@ "repository": "Financial-Times/n-tracking.git", | ||
"@financial-times/o-tracking": "^2.0.3", | ||
"@financial-times/o-viewport": "^4.0.0" | ||
"@financial-times/o-viewport": "^4.0.0", | ||
"perfume.js": "^4.6.0" | ||
}, | ||
@@ -42,0 +43,0 @@ "peerDependencies": { |
@@ -21,18 +21,36 @@ # @financial-times/n-tracking [![CircleCI](https://circleci.com/gh/Financial-Times/n-tracking/tree/master.svg?style=svg)](https://circleci.com/gh/Financial-Times/n-tracking/tree/master) | ||
On the client-side this package can be used to configure [o-tracking], setup click tracking, and send a page view event. | ||
**Configure [o-tracking]** | ||
This package can be used on the client-side. Initialise the component with [configuration options](#options). | ||
```js | ||
import * as nTracking from '@financial-times/n-tracking'; | ||
const options = {} | ||
const oTracking = nTracking.init(options); | ||
``` | ||
**Send custom events** | ||
const oTracking = nTracking.init(options); | ||
```js | ||
import * as nTracking from '@financial-times/n-tracking'; | ||
const context = { customData: 12345 } | ||
nTracking.broadcast('oTracking.event', { | ||
category: 'page', | ||
action: 'custom-event', | ||
...context | ||
}); | ||
``` | ||
To initialise the component you'll need to provide it with several [configuration options](#options). | ||
**Send real-user-monitoring (RUM) performance metrics** | ||
```js | ||
import * as nTracking from '@financial-times/n-tracking'; | ||
if (flags.get('realUserMonitoringForPerformance')) { | ||
nTracking.trackers.realUserMonitoringForPerformance(); | ||
} | ||
``` | ||
<div><img width="70%" src="https://user-images.githubusercontent.com/224547/71626767-c709c480-2be6-11ea-91a5-506972a3b4d7.png" /></div> | ||
_Above: Real-user-monitoring performance metrics are sent to spoor-api._ | ||
### Server-side integration | ||
@@ -75,7 +93,7 @@ | ||
Property | Type | Required | Description | ||
---------------|--------|----------|------------------------------------------------------------------ | ||
`appContext` | Object | Yes | [FT.com App Context] data describing the current page which will be appended to all captured events. | ||
`extraContext` | Object | No | Additional data describing the current page which will be appended to all captured events. | ||
`pageViewContext` | Object | No | Additional data to append to the page view event only | ||
Property | Type | Required | Description | ||
------------------|--------|----------|------------------------------------------------------------------ | ||
`appContext` | Object | Yes | [FT.com App Context] data describing the current page which will be appended to all captured events. | ||
`extraContext` | Object | No | Additional data describing the current page which will be appended to all captured events. | ||
`pageViewContext` | Object | No | Additional data to append to the page view event only | ||
@@ -82,0 +100,0 @@ [FT.com App Context]: https://github.com/Financial-Times/dotcom-page-kit/blob/master/packages/dotcom-server-app-context/schema.md |
@@ -44,2 +44,3 @@ import oTracking from '@financial-times/o-tracking'; | ||
export * from './broadcast'; | ||
// export * from './trackers'; | ||
import * as trackers from './trackers/index.js'; | ||
export { trackers }; |
// TODO: implement and test trackers copied over from n-ui | ||
// https://github.com/Financial-Times/n-ui/tree/master/components/n-ui/tracking/ft/events | ||
export {}; | ||
import { realUserMonitoringForPerformance } from './real-user-monitoring-for-performance'; | ||
export { realUserMonitoringForPerformance }; |
Sorry, the diff of this file is too big to display
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
590888
27
14950
106
5
2
+ Addedperfume.js@^4.6.0
+ Addedperfume.js@4.8.1(transitive)