Skip to content

Commit 2ad7356

Browse files
abeddow91jonflynng
andauthored
Add looping video data- tracking for ophan (#14156)
* Add link name tracking on buttons and component tracking on the video container * explicitly call clickComponent events on looping videos * add explicit clickComponent tracking for play and mute buttons on looping videos * update ophan tracker-js version * bump support-dotcom-components to 7.5.0 * Update the loop video schema to include the atom id. This will be used for tracking. * Remove click component event tracking as it is not required. We recieve enough tracking from the data-link-name * Add data-link play / pause tracking to the video element so clicking on the video tracks this action. * Only track plays when the play icon is clicked. It won't appear when the video is playing so it should never track a pause action. * Track mute or unmute * Align data-component with link name tracking * Remove unnecessary commit * Lift tracking into audio click function --------- Co-authored-by: Jon Flynn <[email protected]>
1 parent 4d6ba05 commit 2ad7356

File tree

10 files changed

+1122
-31
lines changed

10 files changed

+1122
-31
lines changed

dotcom-rendering/package.json

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,12 @@
3838
"@guardian/identity-auth": "6.0.1",
3939
"@guardian/identity-auth-frontend": "8.1.0",
4040
"@guardian/libs": "23.0.0",
41-
"@guardian/ophan-tracker-js": "2.2.10",
41+
"@guardian/ophan-tracker-js": "2.3.0",
4242
"@guardian/react-crossword": "6.3.0",
4343
"@guardian/shimport": "1.0.2",
4444
"@guardian/source": "9.0.0",
4545
"@guardian/source-development-kitchen": "18.1.1",
46-
"@guardian/support-dotcom-components": "7.4.0",
46+
"@guardian/support-dotcom-components": "7.5.0",
4747
"@guardian/tsconfig": "0.2.0",
4848
"@playwright/test": "1.52.0",
4949
"@sentry/browser": "7.75.1",

dotcom-rendering/src/client/ophan/ophan.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,14 @@ export const getOphan = async (
3232
);
3333
}
3434
},
35+
trackClickComponentEvent: (e) => {
36+
if (e instanceof Error) {
37+
window.guardian.modules.sentry.reportError(
38+
e,
39+
"We are in DCAR but Ophan trackClickComponentEvent method got called. This shouldn't have happened. Please investigate why",
40+
);
41+
}
42+
},
3543
viewId: 'Apps',
3644
pageViewId: 'Apps',
3745
};
@@ -73,6 +81,14 @@ export const submitComponentEvent = async (
7381
ophan.record({ componentEvent });
7482
};
7583

84+
export const submitClickComponentEvent = async (
85+
element: Element,
86+
renderingTarget: RenderingTarget,
87+
): Promise<void> => {
88+
const ophan = await getOphan(renderingTarget);
89+
ophan.trackClickComponentEvent(element);
90+
};
91+
7692
interface SdcTestMeta {
7793
abTestName: NonNullable<ComponentEvent['abTest']>['name'];
7894
abTestVariant: NonNullable<ComponentEvent['abTest']>['name'];

dotcom-rendering/src/components/Card/Card.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -915,6 +915,7 @@ export const Card = ({
915915
/>
916916
}
917917
uniqueId={uniqueId}
918+
atomId={media.mainMedia.atomId}
918919
/>
919920
</Island>
920921
)}

dotcom-rendering/src/components/LoopVideo.importable.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { css } from '@emotion/react';
22
import { log } from '@guardian/libs';
33
import { SvgAudio, SvgAudioMute } from '@guardian/source/react-components';
44
import { useEffect, useRef, useState } from 'react';
5+
import { submitClickComponentEvent } from '../client/ophan/ophan';
56
import { getZIndex } from '../lib/getZIndex';
67
import { useIsInView } from '../lib/useIsInView';
78
import { useShouldAdapt } from '../lib/useShouldAdapt';
@@ -33,6 +34,7 @@ export const dispatchCustomPlayAudioEvent = (uniqueId: string) => {
3334

3435
type Props = {
3536
src: string;
37+
atomId: string;
3638
uniqueId: string;
3739
width: number;
3840
height: number;
@@ -42,6 +44,7 @@ type Props = {
4244

4345
export const LoopVideo = ({
4446
src,
47+
atomId,
4548
uniqueId,
4649
width,
4750
height,
@@ -264,6 +267,8 @@ export const LoopVideo = ({
264267
};
265268

266269
const handleAudioClick = (event: React.SyntheticEvent) => {
270+
void submitClickComponentEvent(event.currentTarget, renderingTarget);
271+
267272
event.stopPropagation(); // Don't pause the video
268273

269274
if (isMuted) {
@@ -339,9 +344,11 @@ export const LoopVideo = ({
339344
ref={setNode}
340345
css={videoContainerStyles}
341346
className="loop-video-container"
347+
data-component="gu-video-loop"
342348
>
343349
<LoopVideoPlayer
344350
src={src}
351+
atomId={atomId}
345352
uniqueId={uniqueId}
346353
width={width}
347354
height={height}

dotcom-rendering/src/components/LoopVideoPlayer.tsx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ export const PLAYER_STATES = [
6060

6161
type Props = {
6262
src: string;
63+
atomId: string;
6364
uniqueId: string;
6465
width: number;
6566
height: number;
@@ -88,6 +89,7 @@ export const LoopVideoPlayer = forwardRef(
8889
(
8990
{
9091
src,
92+
atomId,
9193
uniqueId,
9294
width,
9395
height,
@@ -143,6 +145,9 @@ export const LoopVideoPlayer = forwardRef(
143145
tabIndex={0}
144146
onError={onError}
145147
css={videoStyles(width, height)}
148+
data-link-name={`gu-video-loop-${
149+
showPlayIcon ? 'play' : 'pause'
150+
}-${atomId}`}
146151
>
147152
{/* Only mp4 is currently supported. Assumes the video file type is mp4. */}
148153
{/* The start time is set to 1ms so that Safari will autoplay the video */}
@@ -157,6 +162,7 @@ export const LoopVideoPlayer = forwardRef(
157162
type="button"
158163
onClick={handlePlayPauseClick}
159164
css={playIconStyles}
165+
data-link-name={`gu-video-loop-play-${atomId}`}
160166
>
161167
<PlayIcon iconWidth="narrow" />
162168
</button>
@@ -172,6 +178,9 @@ export const LoopVideoPlayer = forwardRef(
172178
type="button"
173179
onClick={handleAudioClick}
174180
css={audioButtonStyles}
181+
data-link-name={`gu-video-loop-${
182+
isMuted ? 'unmute' : 'mute'
183+
}-${atomId}`}
175184
>
176185
<div css={audioIconContainerStyles}>
177186
<AudioIcon

dotcom-rendering/src/frontend/schemas/feArticle.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5247,6 +5247,9 @@
52475247
"type": "string",
52485248
"const": "LoopVideo"
52495249
},
5250+
"atomId": {
5251+
"type": "string"
5252+
},
52505253
"videoId": {
52515254
"type": "string"
52525255
},
@@ -5264,6 +5267,7 @@
52645267
}
52655268
},
52665269
"required": [
5270+
"atomId",
52675271
"duration",
52685272
"height",
52695273
"type",

dotcom-rendering/src/frontend/schemas/feFront.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3914,6 +3914,9 @@
39143914
"type": "string",
39153915
"const": "LoopVideo"
39163916
},
3917+
"atomId": {
3918+
"type": "string"
3919+
},
39173920
"videoId": {
39183921
"type": "string"
39193922
},
@@ -3931,6 +3934,7 @@
39313934
}
39323935
},
39333936
"required": [
3937+
"atomId",
39343938
"duration",
39353939
"height",
39363940
"type",

dotcom-rendering/src/model/enhanceCards.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,7 @@ const getActiveMediaAtom = (
209209
if (asset?.platform === 'Url' && isLoopingVideoTest) {
210210
return {
211211
type: 'LoopVideo',
212+
atomId: mediaAtom.id,
212213
videoId: asset.id,
213214
duration: mediaAtom.duration ?? 0,
214215
// Size fixed to a 5:4 ratio

dotcom-rendering/src/types/mainMedia.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ type Video = Media & {
2121

2222
type LoopVideo = Media & {
2323
type: 'LoopVideo';
24+
atomId: string;
2425
videoId: string;
2526
height: number;
2627
width: number;

0 commit comments

Comments
 (0)