Skip to content

Commit

Permalink
feat: analytics referrer attribution spa
Browse files Browse the repository at this point in the history
- Set up analytics behavior for referrer attribution in SPA;
- Fix additional issues related to analytics context in tracking events;
- Fix inconsistencies in analytics tests.
  • Loading branch information
danielbento92 committed Jan 22, 2024
1 parent eda35d2 commit 034727a
Show file tree
Hide file tree
Showing 4 changed files with 79 additions and 44 deletions.
30 changes: 19 additions & 11 deletions packages/core/src/analytics/Analytics.js
Original file line number Diff line number Diff line change
Expand Up @@ -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<Analytics>} 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)'.",
);
Expand All @@ -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}`,
);
}

Expand Down
31 changes: 18 additions & 13 deletions packages/react/src/analytics/__tests__/analytics.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -168,31 +168,36 @@ 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.

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),
}),
}),
);
});
});
49 changes: 29 additions & 20 deletions packages/react/src/analytics/analytics.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
);
}
}
Expand Down Expand Up @@ -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;
}

/**
Expand All @@ -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;
}
}

Expand Down Expand Up @@ -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;
}
}
Expand Down
13 changes: 13 additions & 0 deletions packages/react/src/analytics/integrations/GA4/GA4.js
Original file line number Diff line number Diff line change
Expand Up @@ -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',
Expand Down

0 comments on commit 034727a

Please sign in to comment.