Source: app/actions/trackingActions.js

import createAction from 'redux-actions/lib/createAction';

export const TRACK_LINK = 'trackingActions/TRACK_LINK';

/**
 * Dispatches a TRACK_LINK action. This will not update any reducer but instead be picked
 * up by redux-listeners-middleware, where actual dataLayer tracking can be performed.
 * @function trackLink
 * @param meta {object} The meta properties that were attached to the LinkTracker component
 * @param href {string} The href for the link that was clicked
 */
export const trackLink = createAction(
  TRACK_LINK,
  (meta, href) => ({ href }),
  meta => meta,
);

export const TRACK_DOM_EVENT = 'trackingActions/TRACK_DOM_EVENT';

/**
 * Dispatches a TRACK_DOM_EVENT action. This will not update any reducer but instead be picked
 * up by redux-listeners-middleware, where actual dataLayer tracking can be performed.
 * @function trackDomEvent
 * @param meta {object} The meta properties that were attached to the DomEventTracker component
 * @param eventType {string} The type of event that was tracked. (for example: onClick)
 * @param tagName {string} The name of the DOM element that was clicked (for example: div, span)
 * @param className {string} The full className of the clicked DOM element
 * @param cid {string} The component id in the className of the clicked DOM element, if available.
 * Otherwise, this will be null
 */
export const trackDomEvent = createAction(
  TRACK_DOM_EVENT,
  (meta, eventType, tagName, className, cid = null) => ({ eventType, tagName, cid, className }),
  meta => meta,
);

export const TRACK_VIDEO_EVENT = 'trackingActions/TRACK_VIDEO_EVENT';

/**
 * Dispatches a TRACK_VIDEO_EVENT action. This will not update any reducer but instead be picked
 * up by redux-listeners-middleware, where actual dataLayer tracking can be performed.
 * @function trackVideoEvent
 * @param meta {object} The meta properties (additional properties)
 * @param eventType {string} Kind of event fired from the video player examples: play, pause
 * @param playerType {string} Kind of player YouTube, Vimeo, Brightcove etc.
 * @param videoId {string} Id of the video displayed
 */
export const trackVideoEvent = createAction(
  TRACK_VIDEO_EVENT,
  (meta, eventType, playerType, videoId) => ({ eventType, playerType, video: videoId }),
  meta => meta,
);

export const COMMON_TRACK_EVENT = 'trackingActions/COMMON_TRACK_EVENT';

/**
 * Dispatches a GENERIC_TRACK_EVENT action. This will not update any reducer but instead be picked
 * up by redux-listeners-middleware, where actual dataLayer tracking can be performed.
 * @function commonTrackEvent
 * @meta {object} The meta properties (additional properties)
 * @param category {string} Tracking category
 * @param action {string} Tracking action
 * @param label {string} Tracking string
 */
export const commonTrackEvent = createAction(
  COMMON_TRACK_EVENT,
  (meta, payload) => payload,
  meta => meta,
);

export const SET_TRACKING_PERSISTENT_DATA = 'trackingActions/SET_TRACKING_PERSISTENT_DATA';

/**
 * Sets event tracking data that will be attached to every future tracking event
 * @function setTrackingPersistentData
 * @param persistentData {object} The new persistentData properties to set
 * @param [merge=true] {boolean} If true, the new properties will be merged into the current meta
 * (by a shallow object assign). Otherwise, will replace the entire current persistentData
 * properties.
 */
export const setTrackingPersistentData = createAction(
  SET_TRACKING_PERSISTENT_DATA,
  (persistentData, merge = true) => ({ persistentData, merge }),
);

export const SET_TRACKING_PAGE_DATA = 'trackingActions/SET_TRACKING_PAGE_DATA';

/**
 * Sets page tracking data that could be attached to every future tracking event
 * @function setTrackingPageData
 * @param pageData {object} The new persistentData properties to set
 * @param [merge=false] {boolean} If true, the new properties will be merged into the current meta
 * (by a shallow object assign). Otherwise, will replace the entire current pageData properties.
 */
export const setTrackingPageData = (pageData, merge = false) => (dispatch, getState) =>
  dispatch(
    createAction(
      SET_TRACKING_PAGE_DATA,
      null,
      null,
    )({
      pathname: getState().routeHistory[0].pathname,
      pageData,
      merge,
    }),
  );

export const PAGE_LOAD_COMPLETE = 'trackingActions/PAGE_LOAD_COMPLETE';

/**
 * Action dispatched on the client side by pageLoadedMiddleware to indicate that all client side
 * initActions have completed for a specific page.
 */
export const pageLoadComplete = createAction(PAGE_LOAD_COMPLETE, location => ({ location }));

export const PAGE_RENDER_COMPLETE = 'trackingActions/PAGE_RENDER_COMPLETE';

/**
 * Action dispatched on to indicate that rendering of components is completed
 */
export const pageRenderComplete = createAction(PAGE_RENDER_COMPLETE);