diff --git a/packages/core/src/analytics/Analytics.js b/packages/core/src/analytics/Analytics.js index 1bbbef796..5917692a2 100644 --- a/packages/core/src/analytics/Analytics.js +++ b/packages/core/src/analytics/Analytics.js @@ -366,15 +366,30 @@ class Analytics { . */ async track(type = trackTypes.TRACK, event, properties, eventContext) { + return this.internalTrack( + await this.getTrackEventData(type, event, properties, eventContext), + ); + } + + /** + * Track method for custom events. + * Call integration's track for active integrations. + * + * @param {object} trackData - Track event data to be sent to integrations. + * + * @returns {Promise} Promise that will resolve with the instance that was used when calling this method to allow chaining. +. + */ + async internalTrack(trackData) { if (!this.isReady) { logger.error( - `Analytics tried to track the event ${event} but failed. Did you forget to call "analytics.ready()?"`, + `Analytics tried to track the event ${trackData.event} but failed. Did you forget to call "analytics.ready()?"`, ); return this; } - if (!event) { + if (!trackData.event) { logger.error( "Please provide a valid event name when calling 'analytics.track(eventName, properties)'.", ); @@ -385,17 +400,10 @@ class Analytics { await this.setUserPromise; try { - const data = await this.getTrackEventData( - type, - event, - properties, - eventContext, - ); - - this.callIntegrationsMethod(this.activeIntegrations, 'track', data); + this.callIntegrationsMethod(this.activeIntegrations, 'track', trackData); } catch (error) { logger.error( - `An error occurred when trying to track event: ${event}: ${error}`, + `An error occurred when trying to track event: ${trackData.event}: ${error}`, ); } diff --git a/packages/react/src/analytics/__tests__/analytics.test.js b/packages/react/src/analytics/__tests__/analytics.test.js index 6764a3535..7eaccbf61 100644 --- a/packages/react/src/analytics/__tests__/analytics.test.js +++ b/packages/react/src/analytics/__tests__/analytics.test.js @@ -168,11 +168,8 @@ describe('analytics web', () => { }); }); - it('Should extend the `track() method for tracking of pages and events`', async () => { - const coreTrackSpy = jest.spyOn( - AnalyticsCore.prototype, - analyticsTrackTypes.TRACK, - ); + it.only('Should extend the `track() method for tracking of pages and events`', async () => { + const coreTrackSpy = jest.spyOn(AnalyticsCore.prototype, 'internalTrack'); const event = 'myEvent'; const properties = {}; const eventContext = { culture: 'pt-PT' }; // Simulate that the event has a different culture associated with it. @@ -180,19 +177,27 @@ describe('analytics web', () => { await analytics.track(event, properties, eventContext); expect(coreTrackSpy).toBeCalledWith( - analyticsTrackTypes.TRACK, - event, - properties, - eventContext, + expect.objectContaining({ + event, + properties, + type: analyticsTrackTypes.TRACK, + context: expect.objectContaining({ + event: expect.objectContaining(eventContext), + }), + }), ); await analytics.page(event, properties, eventContext); expect(coreTrackSpy).toBeCalledWith( - analyticsTrackTypes.PAGE, - event, - properties, - eventContext, + expect.objectContaining({ + event, + properties, + type: analyticsTrackTypes.PAGE, + context: expect.objectContaining({ + event: expect.objectContaining(eventContext), + }), + }), ); }); }); diff --git a/packages/react/src/analytics/analytics.js b/packages/react/src/analytics/analytics.js index 607ce8faf..1d2dfb7ca 100644 --- a/packages/react/src/analytics/analytics.js +++ b/packages/react/src/analytics/analytics.js @@ -52,18 +52,10 @@ class AnalyticsWeb extends Analytics { async onLoadedIntegrations(loadedIntegrations) { // If there is a previous page call data stored, send a page event to the integrations that were loaded by the consent if (this.currentPageCallData) { - const { event, properties } = this.currentPageCallData; - - const pageEventData = await super.getTrackEventData( - analyticsTrackTypes.PAGE, - event, - properties, - ); - super.callIntegrationsMethod( loadedIntegrations, - analyticsTrackTypes.TRACK, - pageEventData, + 'track', // call 'track' method of new integrations loaded + this.currentPageCallData, ); } } @@ -100,8 +92,15 @@ class AnalyticsWeb extends Analytics { * @private */ async getTrackEventData(type, event, properties, eventContext) { - this.processContext(eventContext); - return super.getTrackEventData(type, event, properties, eventContext); + const eventData = super.getTrackEventData( + type, + event, + properties, + eventContext, + ); + + this.processContext(eventData.context); + return eventData; } /** @@ -111,10 +110,23 @@ class AnalyticsWeb extends Analytics { */ processContext(context) { if (context) { - context.library = { + const webLibrary = { name: PCKG_NAME, - version: `${context.library.name}@${context.library.version};${PCKG_NAME}@${PCKG_VERSION};`, + version: `${PCKG_NAME}@${PCKG_VERSION};`, }; + + if (context.library) { + if (context.library.name === PCKG_NAME) { + // in this case, then context already processed by analyticsWeb + return; + } + + // Library already set by analytics core + const { name, version } = context.library; + webLibrary.version = `${name}@${version};${PCKG_NAME}@${PCKG_VERSION};`; + } + + context.library = webLibrary; } } @@ -144,19 +156,16 @@ class AnalyticsWeb extends Analytics { */ async page(event, properties, eventContext) { // Override the last page call data with the current one - this.currentPageCallData = { - event, - properties, - eventContext, - }; - await super.track( + this.currentPageCallData = await this.getTrackEventData( analyticsTrackTypes.PAGE, event, properties, eventContext, ); + await super.internalTrack(this.currentPageCallData); + return this; } } diff --git a/packages/react/src/analytics/integrations/GA4/GA4.js b/packages/react/src/analytics/integrations/GA4/GA4.js index 0f65ce565..95564a94d 100644 --- a/packages/react/src/analytics/integrations/GA4/GA4.js +++ b/packages/react/src/analytics/integrations/GA4/GA4.js @@ -190,6 +190,19 @@ class GA4 extends integrations.Integration { pageViewCommandList.push(...extraCommands); } + const pageLocationReferrer = get( + data, + 'context.web.pageLocationReferrer', + ); + + if (pageLocationReferrer) { + pageViewCommandList.push([ + 'set', + 'page_referrer', + pageLocationReferrer, + ]); + } + pageViewCommandList.push([ 'event', 'page_view',