summaryrefslogtreecommitdiff
path: root/app/assets/javascripts/tracking.js
diff options
context:
space:
mode:
Diffstat (limited to 'app/assets/javascripts/tracking.js')
-rw-r--r--app/assets/javascripts/tracking.js62
1 files changed, 54 insertions, 8 deletions
diff --git a/app/assets/javascripts/tracking.js b/app/assets/javascripts/tracking.js
index 5d82d56f4ba..01de034417e 100644
--- a/app/assets/javascripts/tracking.js
+++ b/app/assets/javascripts/tracking.js
@@ -1,4 +1,16 @@
import { omitBy, isUndefined } from 'lodash';
+import { TRACKING_CONTEXT_SCHEMA } from '~/experimentation/constants';
+import { getExperimentData } from '~/experimentation/utils';
+
+const standardContext = { ...window.gl?.snowplowStandardContext };
+
+export const STANDARD_CONTEXT = {
+ schema: standardContext.schema,
+ data: {
+ ...(standardContext.data || {}),
+ source: 'gitlab-javascript',
+ },
+};
const DEFAULT_SNOWPLOW_OPTIONS = {
namespace: 'gl',
@@ -20,11 +32,17 @@ const createEventPayload = (el, { suffix = '' } = {}) => {
let value = el.dataset.trackValue || el.value || undefined;
if (el.type === 'checkbox' && !el.checked) value = false;
+ let context = el.dataset.trackContext;
+ if (el.dataset.trackExperiment) {
+ const data = getExperimentData(el.dataset.trackExperiment);
+ if (data) context = { schema: TRACKING_CONTEXT_SCHEMA, data };
+ }
+
const data = {
label: el.dataset.trackLabel,
property: el.dataset.trackProperty,
value,
- context: el.dataset.trackContext,
+ context,
};
return {
@@ -51,25 +69,51 @@ const eventHandlers = (category, func) => {
return handlers;
};
+const dispatchEvent = (category = document.body.dataset.page, action = 'generic', data = {}) => {
+ // eslint-disable-next-line @gitlab/require-i18n-strings
+ if (!category) throw new Error('Tracking: no category provided for tracking.');
+
+ const { label, property, value } = data;
+ const contexts = [STANDARD_CONTEXT];
+
+ if (data.context) {
+ contexts.push(data.context);
+ }
+
+ return window.snowplow('trackStructEvent', category, action, label, property, value, contexts);
+};
+
export default class Tracking {
+ static queuedEvents = [];
+ static initialized = false;
+
static trackable() {
return !['1', 'yes'].includes(
window.doNotTrack || navigator.doNotTrack || navigator.msDoNotTrack,
);
}
+ static flushPendingEvents() {
+ this.initialized = true;
+
+ while (this.queuedEvents.length) {
+ dispatchEvent(...this.queuedEvents.shift());
+ }
+ }
+
static enabled() {
return typeof window.snowplow === 'function' && this.trackable();
}
- static event(category = document.body.dataset.page, action = 'generic', data = {}) {
+ static event(...eventData) {
if (!this.enabled()) return false;
- // eslint-disable-next-line @gitlab/require-i18n-strings
- if (!category) throw new Error('Tracking: no category provided for tracking.');
- const { label, property, value, context } = data;
- const contexts = context ? [context] : undefined;
- return window.snowplow('trackStructEvent', category, action, label, property, value, contexts);
+ if (!this.initialized) {
+ this.queuedEvents.push(eventData);
+ return false;
+ }
+
+ return dispatchEvent(...eventData);
}
static bindDocument(category = document.body.dataset.page, parent = document) {
@@ -128,13 +172,15 @@ export function initUserTracking() {
window.snowplow('newTracker', opts.namespace, opts.hostname, opts);
document.dispatchEvent(new Event('SnowplowInitialized'));
+ Tracking.flushPendingEvents();
}
export function initDefaultTrackers() {
if (!Tracking.enabled()) return;
window.snowplow('enableActivityTracking', 30, 30);
- window.snowplow('trackPageView'); // must be after enableActivityTracking
+ // must be after enableActivityTracking
+ window.snowplow('trackPageView', null, [STANDARD_CONTEXT]);
if (window.snowplowOptions.formTracking) window.snowplow('enableFormTracking');
if (window.snowplowOptions.linkClickTracking) window.snowplow('enableLinkClickTracking');