From df6a22b5a67b32b21931aa143ef3119991507479 Mon Sep 17 00:00:00 2001 From: Shayne Marc Enzo Ahchoon Date: Fri, 24 Jan 2025 12:00:04 +0000 Subject: [PATCH 1/6] WSTEAM1-1514: Add lite onclick function --- .../ATIAnalytics/canonical/index.tsx | 3 ++ .../MostRead/Canonical/Item/index.tsx | 6 ++- .../hooks/useClickTrackerHandler/index.jsx | 53 +++++++++++++++++++ .../Renderers/litePageTransforms/index.ts | 3 +- .../transformClickHandlerOption1.ts | 31 +++++++++++ 5 files changed, 94 insertions(+), 2 deletions(-) create mode 100644 src/server/Document/Renderers/litePageTransforms/transformClickHandlerOption1.ts diff --git a/src/app/components/ATIAnalytics/canonical/index.tsx b/src/app/components/ATIAnalytics/canonical/index.tsx index f34dbc15b83..82d04e84fda 100644 --- a/src/app/components/ATIAnalytics/canonical/index.tsx +++ b/src/app/components/ATIAnalytics/canonical/index.tsx @@ -7,6 +7,7 @@ import sendBeacon from '../../../lib/analyticsUtils/sendBeacon'; import { ATIAnalyticsProps } from '../types'; import sendBeaconOperaMiniScript from './sendBeaconOperaMiniScript'; import sendBeaconLite from './sendBeaconLite'; +import { liteTrackingScript } from '#app/hooks/useClickTrackerHandler'; const getNoJsATIPageViewUrl = (atiPageViewUrl: string) => atiPageViewUrl.includes('x8=[simorgh]') @@ -42,9 +43,11 @@ const addOperaMiniExtremeScript = (atiPageViewUrlString: string) => { const addLiteScript = (atiPageViewUrlString: string) => { const script = sendBeaconLite(atiPageViewUrlString); +const clickTrackerScript = liteTrackingScript(); return ( + ); diff --git a/src/app/components/MostRead/Canonical/Item/index.tsx b/src/app/components/MostRead/Canonical/Item/index.tsx index 9b993182848..1ce1eaa38bc 100755 --- a/src/app/components/MostRead/Canonical/Item/index.tsx +++ b/src/app/components/MostRead/Canonical/Item/index.tsx @@ -1,7 +1,9 @@ /** @jsx jsx */ import React, { PropsWithChildren } from 'react'; import { jsx } from '@emotion/react'; -import useClickTrackerHandler from '#hooks/useClickTrackerHandler'; +import useClickTrackerHandler, { + constructLiteSiteURL, +} from '#hooks/useClickTrackerHandler'; import styles from './index.styles'; import { mostReadListGridProps, @@ -47,6 +49,7 @@ export const MostReadLink = ({ eventTrackingData, }: PropsWithChildren) => { const clickTrackerHandler = useClickTrackerHandler(eventTrackingData); + const liteUrl = constructLiteSiteURL(eventTrackingData); return (
@@ -54,6 +57,7 @@ export const MostReadLink = ({ css={[styles.link, size === 'default' && styles.defaultLink]} href={href} onClick={clickTrackerHandler} + add-lite-tracker-params={liteUrl} > {title} diff --git a/src/app/hooks/useClickTrackerHandler/index.jsx b/src/app/hooks/useClickTrackerHandler/index.jsx index 92ae9d74c83..c25b84f6ac9 100644 --- a/src/app/hooks/useClickTrackerHandler/index.jsx +++ b/src/app/hooks/useClickTrackerHandler/index.jsx @@ -7,6 +7,7 @@ import OPTIMIZELY_CONFIG from '../../lib/config/optimizely'; import { sendEventBeacon } from '../../components/ATIAnalytics/beacon/index'; import { ServiceContext } from '../../contexts/ServiceContext'; import { isValidClick } from './clickTypes'; +import { buildATIEventTrackUrl } from '#app/components/ATIAnalytics/atiUrl'; const EVENT_TYPE = 'click'; @@ -136,4 +137,56 @@ const useClickTrackerHandler = (props = {}) => { ); }; +export const LITE_TRACKER_FUNCTION = 'liteTrackerFunction'; + +export const liteTrackingScript = () => { + return `function ${LITE_TRACKER_FUNCTION}(atiURL){ + prompt(atiURL) + }`; +}; + +export const constructLiteSiteURL = props => { + const eventTrackingContext = useContext(EventTrackingContext); + const { service, useReverb } = useContext(ServiceContext); + const optimizelyVariation = + optimizely?.getVariation(OPTIMIZELY_CONFIG.ruleKey) || null; + + const componentName = props?.componentName; + const url = props?.url; + const advertiserID = props?.advertiserID; + const format = props?.format; + const optimizely = props?.optimizely; + const detailedPlacement = props?.detailedPlacement; + + const { + pageIdentifier, + platform, + producerId, + producerName, + statsDestination, + } = eventTrackingContext; + const campaignID = props?.campaignID || eventTrackingContext?.campaignID; + + const atiClickTrackingUrl = buildATIEventTrackUrl({ + campaignID, + componentName, + format, + pageIdentifier, + platform, + producerId, + service, + statsDestination, + type: EVENT_TYPE, + advertiserID, + url, + detailedPlacement, + ...(optimizelyVariation && + optimizelyVariation !== 'off' && { + experimentVariant: optimizelyVariation, + }), + }); + + return atiClickTrackingUrl; +}; + export default useClickTrackerHandler; diff --git a/src/server/Document/Renderers/litePageTransforms/index.ts b/src/server/Document/Renderers/litePageTransforms/index.ts index 15be147383d..14c2f442953 100644 --- a/src/server/Document/Renderers/litePageTransforms/index.ts +++ b/src/server/Document/Renderers/litePageTransforms/index.ts @@ -1,4 +1,5 @@ import transformAnchorTags from './transformAnchorTags'; +import transformClickHandlerOption1 from './transformClickHandlerOption1'; type Fn = (html: string) => string; @@ -7,4 +8,4 @@ const pipe = (x: string) => fns.reduce((result, nextFn) => nextFn(result), x); -export default pipe(transformAnchorTags); +export default pipe(transformAnchorTags, transformClickHandlerOption1); diff --git a/src/server/Document/Renderers/litePageTransforms/transformClickHandlerOption1.ts b/src/server/Document/Renderers/litePageTransforms/transformClickHandlerOption1.ts new file mode 100644 index 00000000000..b521c3b429a --- /dev/null +++ b/src/server/Document/Renderers/litePageTransforms/transformClickHandlerOption1.ts @@ -0,0 +1,31 @@ +import { LITE_TRACKER_FUNCTION } from '#app/hooks/useClickTrackerHandler'; + +export default (html: string) => { + let modifiedHtml = html; + + try { + const tagsWithLiteTracker = + modifiedHtml.match(/<[^>]*\badd-lite-tracker-params[^>]*>/g) || []; + + tagsWithLiteTracker.forEach(tag => { + const matches = tag?.match(/add-lite-tracker-params="([^"]*)"/); + const toReplace = matches?.[0]; + const atiURL = matches?.[1]; + + if (toReplace && atiURL) { + modifiedHtml = modifiedHtml.replace( + tag, + tag.replace( + toReplace, + `onclick='${LITE_TRACKER_FUNCTION}("${atiURL}")'`, + ), + ); + } + }); + } catch (error) { + // eslint-disable-next-line @typescript-eslint/no-empty-function + (() => {})(); + } + + return modifiedHtml; +}; From 22f29fdc7369cff3af8c93fc379f1d933ebcc572 Mon Sep 17 00:00:00 2001 From: Shayne Marc Enzo Ahchoon Date: Fri, 24 Jan 2025 12:57:46 +0000 Subject: [PATCH 2/6] WSTEAM1-1514: Update: --- .../MostRead/Canonical/Item/index.tsx | 8 +- .../hooks/useClickTrackerHandler/index.jsx | 248 ++++++++---------- .../transformClickHandlerOption1.ts | 2 +- 3 files changed, 109 insertions(+), 149 deletions(-) diff --git a/src/app/components/MostRead/Canonical/Item/index.tsx b/src/app/components/MostRead/Canonical/Item/index.tsx index 1ce1eaa38bc..4beafe7d418 100755 --- a/src/app/components/MostRead/Canonical/Item/index.tsx +++ b/src/app/components/MostRead/Canonical/Item/index.tsx @@ -1,5 +1,5 @@ /** @jsx jsx */ -import React, { PropsWithChildren } from 'react'; +import React, { PropsWithChildren, useContext } from 'react'; import { jsx } from '@emotion/react'; import useClickTrackerHandler, { constructLiteSiteURL, @@ -17,6 +17,7 @@ import { } from '../../types'; import { Direction } from '../../../../models/types/global'; import Grid from '../../../../legacy/components/Grid'; +import { RequestContext } from '#app/contexts/RequestContext'; export const getParentColumns = (columnLayout: ColumnLayout) => { return columnLayout !== 'oneColumn' @@ -53,14 +54,13 @@ export const MostReadLink = ({ return (
- {title} - + {children &&
{children}
}
); diff --git a/src/app/hooks/useClickTrackerHandler/index.jsx b/src/app/hooks/useClickTrackerHandler/index.jsx index c25b84f6ac9..d6333b02d4b 100644 --- a/src/app/hooks/useClickTrackerHandler/index.jsx +++ b/src/app/hooks/useClickTrackerHandler/index.jsx @@ -11,20 +11,16 @@ import { buildATIEventTrackUrl } from '#app/components/ATIAnalytics/atiUrl'; const EVENT_TYPE = 'click'; -const useClickTrackerHandler = (props = {}) => { - const preventNavigation = props?.preventNavigation; +const constructBeaconProps = props => { + const eventTrackingContext = useContext(EventTrackingContext); + const { service } = useContext(ServiceContext); + const componentName = props?.componentName; const url = props?.url; const advertiserID = props?.advertiserID; const format = props?.format; - const optimizely = props?.optimizely; - const optimizelyMetricNameOverride = props?.optimizelyMetricNameOverride; const detailedPlacement = props?.detailedPlacement; - const { trackingIsEnabled } = useTrackingToggle(componentName); - const [clicked, setClicked] = useState(false); - const eventTrackingContext = useContext(EventTrackingContext); - const { pageIdentifier, platform, @@ -34,158 +30,122 @@ const useClickTrackerHandler = (props = {}) => { } = eventTrackingContext; const campaignID = props?.campaignID || eventTrackingContext?.campaignID; - const { service, useReverb } = useContext(ServiceContext); + return { + type: EVENT_TYPE, + campaignID, + componentName, + format, + pageIdentifier, + platform, + producerId, + producerName, + service, + advertiserID, + statsDestination, + url, + detailedPlacement, + }; +}; + +const useClickTrackerHandler = (props = {}) => { + const preventNavigation = props?.preventNavigation; + const optimizely = props?.optimizely; + const optimizelyMetricNameOverride = props?.optimizelyMetricNameOverride; + const beaconProps = constructBeaconProps(props); + const { + campaignID, + componentName, + pageIdentifier, + platform, + producerId, + producerName, + service, + statsDestination, + } = beaconProps; + + const { trackingIsEnabled } = useTrackingToggle(componentName); + const [clicked, setClicked] = useState(false); - return useCallback( - async event => { - const shouldRegisterClick = [ - trackingIsEnabled, - !clicked, - isValidClick(event), + const { useReverb } = useContext(ServiceContext); + console.log('OUTSIDE USE CALLBACK'); + return useCallback(async event => { + const shouldRegisterClick = [ + trackingIsEnabled, + !clicked, + isValidClick(event), + ].every(Boolean); + if (shouldRegisterClick) { + setClicked(true); + console.log('INSIDE USE CALLBACK'); + const shouldSendEvent = [ + campaignID, + componentName, + pageIdentifier, + platform, + producerId, + producerName, + service, + statsDestination, ].every(Boolean); - if (shouldRegisterClick) { - setClicked(true); - - const shouldSendEvent = [ - campaignID, - componentName, - pageIdentifier, - platform, - producerId, - producerName, - service, - statsDestination, - ].every(Boolean); - if (shouldSendEvent) { - const nextPageUrl = event?.currentTarget?.href; - - event.stopPropagation(); - event.preventDefault(); - - if (optimizely) { - const eventName = OPTIMIZELY_CONFIG.viewClickAttributeId; - - const overrideAttributes = { - ...optimizely.user.attributes, - [`clicked_${eventName}`]: true, - }; - - optimizely.track( - optimizelyMetricNameOverride - ? `${optimizelyMetricNameOverride}_clicks` - : 'component_clicks', - optimizely.user.id, - overrideAttributes, - ); - } + if (shouldSendEvent) { + const nextPageUrl = event?.currentTarget?.href; + + event.stopPropagation(); + event.preventDefault(); + + if (optimizely) { + const eventName = OPTIMIZELY_CONFIG.viewClickAttributeId; + + const overrideAttributes = { + ...optimizely.user.attributes, + [`clicked_${eventName}`]: true, + }; + + optimizely.track( + optimizelyMetricNameOverride + ? `${optimizelyMetricNameOverride}_clicks` + : 'component_clicks', + optimizely.user.id, + overrideAttributes, + ); + } - const optimizelyVariation = - optimizely?.getVariation(OPTIMIZELY_CONFIG.ruleKey) || null; - - try { - await sendEventBeacon({ - type: EVENT_TYPE, - campaignID, - componentName, - format, - pageIdentifier, - platform, - producerId, - producerName, - service, - advertiserID, - statsDestination, - url, - detailedPlacement, - useReverb, - ...(optimizelyVariation && - optimizelyVariation !== 'off' && { - experimentVariant: optimizelyVariation, - }), - }); - } finally { - if (nextPageUrl && !preventNavigation) { - if (optimizely) { - optimizely.close(); - } - window.location.assign(nextPageUrl); + const optimizelyVariation = + optimizely?.getVariation(OPTIMIZELY_CONFIG.ruleKey) || null; + + try { + await sendEventBeacon({ + ...beaconProps, + useReverb, + ...(optimizelyVariation && + optimizelyVariation !== 'off' && { + experimentVariant: optimizelyVariation, + }), + }); + } finally { + if (nextPageUrl && !preventNavigation) { + if (optimizely) { + optimizely.close(); } + window.location.assign(nextPageUrl); } } } - }, - [ - trackingIsEnabled, - clicked, - campaignID, - componentName, - pageIdentifier, - platform, - preventNavigation, - producerId, - producerName, - service, - statsDestination, - url, - advertiserID, - format, - optimizely, - optimizelyMetricNameOverride, - detailedPlacement, - useReverb, - ], - ); + } + }, Object.keys(beaconProps)); }; export const LITE_TRACKER_FUNCTION = 'liteTrackerFunction'; export const liteTrackingScript = () => { - return `function ${LITE_TRACKER_FUNCTION}(atiURL){ - prompt(atiURL) + return `function ${LITE_TRACKER_FUNCTION}(event, atiURL){ + console.log(event, atiURL); }`; }; export const constructLiteSiteURL = props => { - const eventTrackingContext = useContext(EventTrackingContext); - const { service, useReverb } = useContext(ServiceContext); - const optimizelyVariation = - optimizely?.getVariation(OPTIMIZELY_CONFIG.ruleKey) || null; - - const componentName = props?.componentName; - const url = props?.url; - const advertiserID = props?.advertiserID; - const format = props?.format; - const optimizely = props?.optimizely; - const detailedPlacement = props?.detailedPlacement; - - const { - pageIdentifier, - platform, - producerId, - producerName, - statsDestination, - } = eventTrackingContext; - const campaignID = props?.campaignID || eventTrackingContext?.campaignID; - - const atiClickTrackingUrl = buildATIEventTrackUrl({ - campaignID, - componentName, - format, - pageIdentifier, - platform, - producerId, - service, - statsDestination, - type: EVENT_TYPE, - advertiserID, - url, - detailedPlacement, - ...(optimizelyVariation && - optimizelyVariation !== 'off' && { - experimentVariant: optimizelyVariation, - }), - }); - + const beaconProps = constructBeaconProps(props); + const atiClickTrackingUrl = buildATIEventTrackUrl(beaconProps); return atiClickTrackingUrl; }; diff --git a/src/server/Document/Renderers/litePageTransforms/transformClickHandlerOption1.ts b/src/server/Document/Renderers/litePageTransforms/transformClickHandlerOption1.ts index b521c3b429a..f04ab8aa721 100644 --- a/src/server/Document/Renderers/litePageTransforms/transformClickHandlerOption1.ts +++ b/src/server/Document/Renderers/litePageTransforms/transformClickHandlerOption1.ts @@ -17,7 +17,7 @@ export default (html: string) => { tag, tag.replace( toReplace, - `onclick='${LITE_TRACKER_FUNCTION}("${atiURL}")'`, + `onclick='${LITE_TRACKER_FUNCTION}(event, "${atiURL}")'`, ), ); } From 87a5c0c4e8920e7e49dfd53e20439b304cc2cdb0 Mon Sep 17 00:00:00 2001 From: alex-magana Date: Fri, 24 Jan 2025 20:09:40 +0300 Subject: [PATCH 3/6] Invoke click tracker handler --- src/app/components/ATIAnalytics/canonical/index.tsx | 2 +- .../ATIAnalytics/canonical/sendBeaconLite.ts | 12 ++++++++---- src/app/components/MostRead/Canonical/Item/index.tsx | 7 ++++--- src/app/components/MostRead/index.tsx | 5 ++++- src/app/hooks/useClickTrackerHandler/index.jsx | 12 +++++++++++- 5 files changed, 28 insertions(+), 10 deletions(-) diff --git a/src/app/components/ATIAnalytics/canonical/index.tsx b/src/app/components/ATIAnalytics/canonical/index.tsx index 82d04e84fda..08ba24a8c56 100644 --- a/src/app/components/ATIAnalytics/canonical/index.tsx +++ b/src/app/components/ATIAnalytics/canonical/index.tsx @@ -43,7 +43,7 @@ const addOperaMiniExtremeScript = (atiPageViewUrlString: string) => { const addLiteScript = (atiPageViewUrlString: string) => { const script = sendBeaconLite(atiPageViewUrlString); -const clickTrackerScript = liteTrackingScript(); + const clickTrackerScript = liteTrackingScript(); return ( diff --git a/src/app/components/ATIAnalytics/canonical/sendBeaconLite.ts b/src/app/components/ATIAnalytics/canonical/sendBeaconLite.ts index 387975e2e95..7f48a1030e9 100644 --- a/src/app/components/ATIAnalytics/canonical/sendBeaconLite.ts +++ b/src/app/components/ATIAnalytics/canonical/sendBeaconLite.ts @@ -1,8 +1,12 @@ const sendBeaconLite = (atiPageViewUrlString: string) => ` - var xhr = new XMLHttpRequest(); - xhr.open("GET", "${atiPageViewUrlString}", true); - xhr.withCredentials = true; - xhr.send(); + function sendBeaconLite (atiPageViewUrlString) { + var xhr = new XMLHttpRequest(); + xhr.open("GET", atiPageViewUrlString, true); + xhr.withCredentials = true; + xhr.send(); + } + + sendBeaconLite("${atiPageViewUrlString}"); `; export default sendBeaconLite; diff --git a/src/app/components/MostRead/Canonical/Item/index.tsx b/src/app/components/MostRead/Canonical/Item/index.tsx index 4beafe7d418..bbeced51c2a 100755 --- a/src/app/components/MostRead/Canonical/Item/index.tsx +++ b/src/app/components/MostRead/Canonical/Item/index.tsx @@ -54,13 +54,14 @@ export const MostReadLink = ({ return (
- + {children &&
{children}
}
); diff --git a/src/app/components/MostRead/index.tsx b/src/app/components/MostRead/index.tsx index 15e5469ef5c..254a5173d13 100644 --- a/src/app/components/MostRead/index.tsx +++ b/src/app/components/MostRead/index.tsx @@ -114,7 +114,7 @@ const MostRead = ({ className = '', sendOptimizelyEvents = false, }: MostReadProps) => { - const { isAmp, pageType, variant } = useContext(RequestContext); + const { isLite, isAmp, pageType, variant } = useContext(RequestContext); const { optimizely } = useContext(OptimizelyContext); const { service, @@ -145,6 +145,9 @@ const MostRead = ({ optimizely, optimizelyMetricNameOverride: 'most_read', }), + ...(isLite && { + liteSiteUrl: 'liteSiteUrl', + }) }; return isAmp ? ( diff --git a/src/app/hooks/useClickTrackerHandler/index.jsx b/src/app/hooks/useClickTrackerHandler/index.jsx index d6333b02d4b..acf20917c24 100644 --- a/src/app/hooks/useClickTrackerHandler/index.jsx +++ b/src/app/hooks/useClickTrackerHandler/index.jsx @@ -2,6 +2,7 @@ import { useContext, useCallback, useState } from 'react'; import { EventTrackingContext } from '../../contexts/EventTrackingContext'; +import { RequestContext } from '../../contexts/RequestContext'; import useTrackingToggle from '../useTrackingToggle'; import OPTIMIZELY_CONFIG from '../../lib/config/optimizely'; import { sendEventBeacon } from '../../components/ATIAnalytics/beacon/index'; @@ -139,7 +140,16 @@ export const LITE_TRACKER_FUNCTION = 'liteTrackerFunction'; export const liteTrackingScript = () => { return `function ${LITE_TRACKER_FUNCTION}(event, atiURL){ - console.log(event, atiURL); + // console.log(event, atiURL); + + event.stopPropagation(); + event.preventDefault(); + + var nextPageUrl = event.currentTarget.href; + + sendBeaconLite(atiURL); + + window.location.assign(nextPageUrl); }`; }; From bb028be478a7531cdf1ead9bc5ac901711269ffe Mon Sep 17 00:00:00 2001 From: Shayne Marc Enzo Ahchoon Date: Mon, 27 Jan 2025 13:01:44 +0000 Subject: [PATCH 4/6] WSTEAM1-1514: Update ati url to include client side params --- .../hooks/useClickTrackerHandler/index.jsx | 55 ++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) diff --git a/src/app/hooks/useClickTrackerHandler/index.jsx b/src/app/hooks/useClickTrackerHandler/index.jsx index acf20917c24..c6dea2c0b10 100644 --- a/src/app/hooks/useClickTrackerHandler/index.jsx +++ b/src/app/hooks/useClickTrackerHandler/index.jsx @@ -146,8 +146,61 @@ export const liteTrackingScript = () => { event.preventDefault(); var nextPageUrl = event.currentTarget.href; + + const { screen: {width, height, colorDepth, pixelDepth}, innerWidth, innerHeight } = window; + const now = new Date(); + const hours = now.getHours(); + const mins = now.getMinutes(); + const secs = now.getSeconds(); + + function getCookie () { + const cookieName = 'atuserid'; + const expires = 397; // expires in 13 months + let value = \`; $\{document.cookie\}\`; + let parts = value.split(\`; $\{cookieName\}=\`); + let user = null; + + if (parts.length === 2){ + user = parts.pop().split(';').shift(); + if(!user && crypto.randomUUID){ + user = crypto.randomUUID(); + } + } + + if(user){ + document.cookie = \`$\{cookieName\}=$\{uid\}; path=/; max-age=$\{expires\};\`; + } + + return user; + } - sendBeaconLite(atiURL); + const rValue = [ + width || 0, + height || 0, + colorDepth || 0, + pixelDepth || 0, + ].join('x') + + const reValue = [innerWidth || 0, innerHeight || 0].join('x'); + + const hlValue = [hours, mins, secs].join('x'); + + let clientSideAtiURL = atiURL + .concat('&', 'r=', rValue) + .concat('&', 're=', reValue) + .concat('&', 'hl=', hlValue) + + if (navigator.language) { + clientSideAtiURL = clientSideAtiURL.concat('&', 'lng=', navigator.language) + } + + const cookieId = getCookie(); + console.log("CHECK", cookieId) + if (cookieId) { + clientSideAtiURL = clientSideAtiURL.concat('&', 'idclient=', cookieId) + } + + sendBeaconLite(clientSideAtiURL); window.location.assign(nextPageUrl); }`; From ed6b06bf438427041a9759e453a4c24f7a977612 Mon Sep 17 00:00:00 2001 From: emilysaffron Date: Mon, 27 Jan 2025 16:08:15 +0000 Subject: [PATCH 5/6] add click tracking to lite site cta --- .../ATIAnalytics/canonical/index.tsx | 2 +- src/app/components/LiteSiteCta/index.tsx | 14 +++++++++++ .../hooks/useClickTrackerHandler/index.jsx | 23 +++++++++++-------- 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/src/app/components/ATIAnalytics/canonical/index.tsx b/src/app/components/ATIAnalytics/canonical/index.tsx index 08ba24a8c56..68c23423632 100644 --- a/src/app/components/ATIAnalytics/canonical/index.tsx +++ b/src/app/components/ATIAnalytics/canonical/index.tsx @@ -3,11 +3,11 @@ import { getEnvConfig } from '#app/lib/utilities/getEnvConfig'; import { RequestContext } from '#app/contexts/RequestContext'; import isOperaProxy from '#app/lib/utilities/isOperaProxy'; import { Helmet } from 'react-helmet'; +import { liteTrackingScript } from '#app/hooks/useClickTrackerHandler'; import sendBeacon from '../../../lib/analyticsUtils/sendBeacon'; import { ATIAnalyticsProps } from '../types'; import sendBeaconOperaMiniScript from './sendBeaconOperaMiniScript'; import sendBeaconLite from './sendBeaconLite'; -import { liteTrackingScript } from '#app/hooks/useClickTrackerHandler'; const getNoJsATIPageViewUrl = (atiPageViewUrl: string) => atiPageViewUrl.includes('x8=[simorgh]') diff --git a/src/app/components/LiteSiteCta/index.tsx b/src/app/components/LiteSiteCta/index.tsx index 8a06d3207e9..74203d359d6 100644 --- a/src/app/components/LiteSiteCta/index.tsx +++ b/src/app/components/LiteSiteCta/index.tsx @@ -1,6 +1,9 @@ /** @jsx jsx */ import { useContext } from 'react'; import { jsx } from '@emotion/react'; +import useClickTrackerHandler, { + constructLiteSiteURL, +} from '#app/hooks/useClickTrackerHandler'; import Paragraph from '../Paragraph'; import Text from '../Text'; import { LeftChevron, RightChevron } from '../icons'; @@ -17,6 +20,7 @@ type CtaLinkProps = { showChevron?: boolean; ignoreLiteExtension?: boolean; className?: string; + eventTrackingData: { componentName: string }; }; const CtaLink = ({ @@ -27,6 +31,7 @@ const CtaLink = ({ showChevron = false, ignoreLiteExtension = false, className, + eventTrackingData, }: CtaLinkProps) => { const chevron = isRtl ? ( @@ -34,11 +39,16 @@ const CtaLink = ({ ); + const clickTrackerHandler = useClickTrackerHandler(eventTrackingData); + const liteUrl = constructLiteSiteURL(eventTrackingData); + return ( @@ -62,6 +72,8 @@ const LiteSiteCta = () => { dataSaving, } = liteSite; const id = 'LiteSiteCta'; + const eventTrackingDataSiteSwitch = { componentName: 'switch-to-canonical' }; + const eventTrackingLiteSiteInfo = { componentName: 'lite-site-info' }; return (
{ css={styles.topLinkSpacing} ignoreLiteExtension showChevron + eventTrackingData={eventTrackingDataSiteSwitch} /> @@ -94,6 +107,7 @@ const LiteSiteCta = () => { href={informationPageLink} text={informationPage} css={styles.bottomLinkSpacing} + eventTrackingData={eventTrackingLiteSiteInfo} />
diff --git a/src/app/hooks/useClickTrackerHandler/index.jsx b/src/app/hooks/useClickTrackerHandler/index.jsx index c6dea2c0b10..b3c1fa853e4 100644 --- a/src/app/hooks/useClickTrackerHandler/index.jsx +++ b/src/app/hooks/useClickTrackerHandler/index.jsx @@ -158,20 +158,25 @@ export const liteTrackingScript = () => { const expires = 397; // expires in 13 months let value = \`; $\{document.cookie\}\`; let parts = value.split(\`; $\{cookieName\}=\`); - let user = null; - + let val = null; + if (parts.length === 2){ - user = parts.pop().split(';').shift(); - if(!user && crypto.randomUUID){ - user = crypto.randomUUID(); + const cookie = parts.pop().split(';').shift(); + if(cookie){ + let decodedCookie = decodeURI(cookie); + const user = JSON.parse(decodedCookie); + val = user.val; + } + else if(crypto.randomUUID){ + val = JSON.stringify({val:crypto.randomUUID()}); } } - if(user){ - document.cookie = \`$\{cookieName\}=$\{uid\}; path=/; max-age=$\{expires\};\`; + if(val){ + document.cookie = \`$\{cookieName\}=$\{val\}; path=/; max-age=$\{expires\};\`; } - return user; + return val; } const rValue = [ @@ -195,7 +200,7 @@ export const liteTrackingScript = () => { } const cookieId = getCookie(); - console.log("CHECK", cookieId) + if (cookieId) { clientSideAtiURL = clientSideAtiURL.concat('&', 'idclient=', cookieId) } From a0b70d4a753b6d3a58dfee61461b179351f0b9d7 Mon Sep 17 00:00:00 2001 From: Shayne Marc Enzo Ahchoon Date: Mon, 27 Jan 2025 16:43:21 +0000 Subject: [PATCH 6/6] WSTEAM1-1514: Update --- .../hooks/useClickTrackerHandler/index.jsx | 62 +++++++++---------- 1 file changed, 29 insertions(+), 33 deletions(-) diff --git a/src/app/hooks/useClickTrackerHandler/index.jsx b/src/app/hooks/useClickTrackerHandler/index.jsx index b3c1fa853e4..4187e7cc10b 100644 --- a/src/app/hooks/useClickTrackerHandler/index.jsx +++ b/src/app/hooks/useClickTrackerHandler/index.jsx @@ -68,7 +68,7 @@ const useClickTrackerHandler = (props = {}) => { const [clicked, setClicked] = useState(false); const { useReverb } = useContext(ServiceContext); - console.log('OUTSIDE USE CALLBACK'); + return useCallback(async event => { const shouldRegisterClick = [ trackingIsEnabled, @@ -77,7 +77,7 @@ const useClickTrackerHandler = (props = {}) => { ].every(Boolean); if (shouldRegisterClick) { setClicked(true); - console.log('INSIDE USE CALLBACK'); + const shouldSendEvent = [ campaignID, componentName, @@ -140,45 +140,43 @@ export const LITE_TRACKER_FUNCTION = 'liteTrackerFunction'; export const liteTrackingScript = () => { return `function ${LITE_TRACKER_FUNCTION}(event, atiURL){ - // console.log(event, atiURL); - event.stopPropagation(); event.preventDefault(); var nextPageUrl = event.currentTarget.href; - + const { screen: {width, height, colorDepth, pixelDepth}, innerWidth, innerHeight } = window; const now = new Date(); const hours = now.getHours(); const mins = now.getMinutes(); const secs = now.getSeconds(); - - function getCookie () { - const cookieName = 'atuserid'; - const expires = 397; // expires in 13 months - let value = \`; $\{document.cookie\}\`; - let parts = value.split(\`; $\{cookieName\}=\`); - let val = null; - if (parts.length === 2){ - const cookie = parts.pop().split(';').shift(); - if(cookie){ - let decodedCookie = decodeURI(cookie); - const user = JSON.parse(decodedCookie); - val = user.val; - } - else if(crypto.randomUUID){ - val = JSON.stringify({val:crypto.randomUUID()}); - } - } - - if(val){ - document.cookie = \`$\{cookieName\}=$\{val\}; path=/; max-age=$\{expires\};\`; + // COOKIE SETTINGS + const cookieName = 'atuserid'; + const expires = 397; // expires in 13 months + let cookiesForPage = \`; $\{document.cookie\}\`; + let atUserIdCookie = cookiesForPage.split(\`; $\{cookieName\}=\`); + let atUserIdValue = null; + + if (atUserIdCookie.length === 2){ + const cookieInfo = atUserIdCookie.pop().split(';').shift(); + + if(cookieInfo){ + let decodedCookie = decodeURI(cookieInfo); + const user = JSON.parse(decodedCookie); + atUserIdValue = user.val; } - - return val; + } + + if(!atUserIdValue && crypto.randomUUID){ + atUserIdValue = crypto.randomUUID(); } + const stringifiedCookieValue = JSON.stringify({val: atUserIdValue}); + if(atUserIdValue){ + document.cookie = \`$\{cookieName\}=$\{stringifiedCookieValue\}; path=/; max-age=$\{expires\};\`; + } + const rValue = [ width || 0, height || 0, @@ -198,11 +196,9 @@ export const liteTrackingScript = () => { if (navigator.language) { clientSideAtiURL = clientSideAtiURL.concat('&', 'lng=', navigator.language) } - - const cookieId = getCookie(); - - if (cookieId) { - clientSideAtiURL = clientSideAtiURL.concat('&', 'idclient=', cookieId) + + if (atUserIdValue) { + clientSideAtiURL = clientSideAtiURL.concat('&', 'idclient=', atUserIdValue) } sendBeaconLite(clientSideAtiURL);