From c34298ac92b31333f2fee907a5687ef35ccefa12 Mon Sep 17 00:00:00 2001 From: David Furey Date: Wed, 22 Apr 2026 15:08:43 +0100 Subject: [PATCH 1/2] Expect frontend to supply audio ad urls Rather than adding flex.acast.com prefix, frontend should provide ad urls for audio elements and audio atoms --- .../fixtures/generated/fe-articles/Audio.ts | 2 ++ .../components/AudioAtom/AudioAtom.stories.tsx | 2 ++ .../components/AudioAtom/AudioAtom.test.tsx | 4 ++++ .../src/components/AudioAtom/AudioAtom.tsx | 18 +++++++++++------- .../src/components/AudioAtomWrapper.island.tsx | 3 +++ .../components/AudioPlayerWrapper.island.tsx | 8 ++++---- .../src/frontend/schemas/feArticle.json | 12 ++++++++++-- dotcom-rendering/src/layouts/AudioLayout.tsx | 3 +++ dotcom-rendering/src/lib/audio-data.ts | 8 +++++++- dotcom-rendering/src/lib/renderElement.tsx | 1 + dotcom-rendering/src/model/block-schema.json | 12 ++++++++++-- dotcom-rendering/src/types/content.ts | 2 ++ 12 files changed, 59 insertions(+), 16 deletions(-) diff --git a/dotcom-rendering/fixtures/generated/fe-articles/Audio.ts b/dotcom-rendering/fixtures/generated/fe-articles/Audio.ts index 76743078418..656b3477827 100644 --- a/dotcom-rendering/fixtures/generated/fe-articles/Audio.ts +++ b/dotcom-rendering/fixtures/generated/fe-articles/Audio.ts @@ -32,6 +32,8 @@ export const Audio: FEArticle = { source: 'The Guardian', }, url: 'https://audio.guim.co.uk/2026/02/27-42462-gdn.alr.060326.NA_GAVIN_FRANCIS_MENTALILLNESS.mp3', + urlWithAds: + 'https://flex.acast.com/audio.guim.co.uk/2026/02/27-42462-gdn.alr.060326.NA_GAVIN_FRANCIS_MENTALILLNESS.mp3', mimeType: 'audio/mpeg', }, ], diff --git a/dotcom-rendering/src/components/AudioAtom/AudioAtom.stories.tsx b/dotcom-rendering/src/components/AudioAtom/AudioAtom.stories.tsx index 817c1c69e5b..5e9a82e6eb2 100644 --- a/dotcom-rendering/src/components/AudioAtom/AudioAtom.stories.tsx +++ b/dotcom-rendering/src/components/AudioAtom/AudioAtom.stories.tsx @@ -13,6 +13,8 @@ export const AudioAtom = meta.story({ id: 'd6d509cf-ca10-407f-8913-e16a3712f415', trackUrl: 'https://audio.guim.co.uk/2020/05/05-61553-gnl.fw.200505.jf.ch7DW.mp3', + trackUrlWithAds: + 'https://audio.guim.co.uk/2020/05/05-61553-gnl.fw.200505.jf.ch7DW.mp3?ads=true', kicker: 'Football Weekly Extra Extra', title: 'Q&A and Detective Wilson', duration: 849, diff --git a/dotcom-rendering/src/components/AudioAtom/AudioAtom.test.tsx b/dotcom-rendering/src/components/AudioAtom/AudioAtom.test.tsx index ef3d2b07ff0..0c0a2341dfa 100644 --- a/dotcom-rendering/src/components/AudioAtom/AudioAtom.test.tsx +++ b/dotcom-rendering/src/components/AudioAtom/AudioAtom.test.tsx @@ -14,6 +14,7 @@ describe('AudioAtom', () => { { { { ( ); -const buildUrl = (basicUrl: string, shouldUseAcast?: boolean) => { - return shouldUseAcast - ? basicUrl.replace('https://', 'https://flex.acast.com/') - : basicUrl; +const buildUrl = ( + basicUrl: string, + urlWithAds: string, + shouldUseAcast?: boolean, +) => { + return shouldUseAcast ? urlWithAds : basicUrl; }; type Props = { @@ -197,12 +199,14 @@ type Props = { kicker: string; title?: string; shouldUseAcast?: boolean; + trackUrlWithAds: string; duration: number; }; export const AudioAtom = ({ id, trackUrl, + trackUrlWithAds, kicker, title, shouldUseAcast, @@ -216,7 +220,7 @@ export const AudioAtom = ({ const [percentPlayed, setPercentPlayed] = useState(0); // url const [urlToUse, setUrlToUse] = useState( - buildUrl(trackUrl, shouldUseAcast), + buildUrl(trackUrl, trackUrlWithAds, shouldUseAcast), ); useEffect(() => { @@ -303,8 +307,8 @@ export const AudioAtom = ({ // If Acast is enabled, replace the default url with an ad enabled one useEffect(() => { - setUrlToUse(buildUrl(trackUrl, shouldUseAcast)); - }, [shouldUseAcast, trackUrl]); + setUrlToUse(buildUrl(trackUrl, trackUrlWithAds, shouldUseAcast)); + }, [shouldUseAcast, trackUrl, trackUrlWithAds]); const playAudio = () => { setIsPlaying(true); diff --git a/dotcom-rendering/src/components/AudioAtomWrapper.island.tsx b/dotcom-rendering/src/components/AudioAtomWrapper.island.tsx index e8d531610f4..55d11859b62 100644 --- a/dotcom-rendering/src/components/AudioAtomWrapper.island.tsx +++ b/dotcom-rendering/src/components/AudioAtomWrapper.island.tsx @@ -5,6 +5,7 @@ import { AudioAtom } from './AudioAtom/AudioAtom'; type Props = { id: string; trackUrl: string; + trackUrlWithAds: string; kicker: string; title?: string | undefined; duration: number; @@ -26,6 +27,7 @@ type Props = { export const AudioAtomWrapper = ({ id, trackUrl, + trackUrlWithAds, kicker, title, duration, @@ -58,6 +60,7 @@ export const AudioAtomWrapper = ({ ; }; diff --git a/dotcom-rendering/src/frontend/schemas/feArticle.json b/dotcom-rendering/src/frontend/schemas/feArticle.json index c3d1e9c404b..f2ede600760 100644 --- a/dotcom-rendering/src/frontend/schemas/feArticle.json +++ b/dotcom-rendering/src/frontend/schemas/feArticle.json @@ -938,6 +938,9 @@ "trackUrl": { "type": "string" }, + "trackUrlWithAds": { + "type": "string" + }, "duration": { "type": "number" }, @@ -955,7 +958,8 @@ "elementId", "id", "kicker", - "trackUrl" + "trackUrl", + "trackUrlWithAds" ] }, "RoleType": { @@ -1002,6 +1006,9 @@ "url": { "type": "string" }, + "urlWithAds": { + "type": "string" + }, "mimeType": { "type": "string" }, @@ -1024,7 +1031,8 @@ } }, "required": [ - "url" + "url", + "urlWithAds" ] }, "BlockquoteBlockElement": { diff --git a/dotcom-rendering/src/layouts/AudioLayout.tsx b/dotcom-rendering/src/layouts/AudioLayout.tsx index d3b68d8c2ba..5225f3a32ae 100644 --- a/dotcom-rendering/src/layouts/AudioLayout.tsx +++ b/dotcom-rendering/src/layouts/AudioLayout.tsx @@ -335,6 +335,9 @@ export const AudioLayout = (props: WebProps | AppProps) => { !!article.config.switches.acast } src={audioData.audioDownloadUrl} + srcWithAds={ + audioData.audioDownloadUrlWithAds + } mediaId={audioData.mediaId} /> diff --git a/dotcom-rendering/src/lib/audio-data.ts b/dotcom-rendering/src/lib/audio-data.ts index 3527de50ea1..22a07ccfeb3 100644 --- a/dotcom-rendering/src/lib/audio-data.ts +++ b/dotcom-rendering/src/lib/audio-data.ts @@ -3,7 +3,12 @@ import type { FEElement } from '../types/content'; export const getAudioData = ( mainMediaElements: FEElement[] | undefined, ): - | { audioDownloadUrl: string; mediaId: string; durationSeconds?: number } + | { + audioDownloadUrl: string; + audioDownloadUrlWithAds: string; + mediaId: string; + durationSeconds?: number; + } | undefined => { const audioBlockElement = mainMediaElements?.find( (element) => @@ -17,6 +22,7 @@ export const getAudioData = ( const total = (isNaN(mins) ? 0 : mins) * 60 + (isNaN(secs) ? 0 : secs); return { audioDownloadUrl: audioBlockElement.assets[0].url, + audioDownloadUrlWithAds: audioBlockElement.assets[0].urlWithAds, mediaId: audioBlockElement.id, durationSeconds: total > 0 ? total : undefined, }; diff --git a/dotcom-rendering/src/lib/renderElement.tsx b/dotcom-rendering/src/lib/renderElement.tsx index 2277dea5826..1eb19ce3907 100644 --- a/dotcom-rendering/src/lib/renderElement.tsx +++ b/dotcom-rendering/src/lib/renderElement.tsx @@ -189,6 +189,7 @@ export const renderElement = ({ Date: Fri, 24 Apr 2026 15:35:49 +0100 Subject: [PATCH 2/2] Push acast decision up to atom wrapper Responding to PR feedback --- .../AudioAtom/AudioAtom.stories.tsx | 2 -- .../components/AudioAtom/AudioAtom.test.tsx | 4 --- .../src/components/AudioAtom/AudioAtom.tsx | 27 +++---------------- .../components/AudioAtomWrapper.island.tsx | 5 ++-- 4 files changed, 5 insertions(+), 33 deletions(-) diff --git a/dotcom-rendering/src/components/AudioAtom/AudioAtom.stories.tsx b/dotcom-rendering/src/components/AudioAtom/AudioAtom.stories.tsx index 5e9a82e6eb2..817c1c69e5b 100644 --- a/dotcom-rendering/src/components/AudioAtom/AudioAtom.stories.tsx +++ b/dotcom-rendering/src/components/AudioAtom/AudioAtom.stories.tsx @@ -13,8 +13,6 @@ export const AudioAtom = meta.story({ id: 'd6d509cf-ca10-407f-8913-e16a3712f415', trackUrl: 'https://audio.guim.co.uk/2020/05/05-61553-gnl.fw.200505.jf.ch7DW.mp3', - trackUrlWithAds: - 'https://audio.guim.co.uk/2020/05/05-61553-gnl.fw.200505.jf.ch7DW.mp3?ads=true', kicker: 'Football Weekly Extra Extra', title: 'Q&A and Detective Wilson', duration: 849, diff --git a/dotcom-rendering/src/components/AudioAtom/AudioAtom.test.tsx b/dotcom-rendering/src/components/AudioAtom/AudioAtom.test.tsx index 0c0a2341dfa..ef3d2b07ff0 100644 --- a/dotcom-rendering/src/components/AudioAtom/AudioAtom.test.tsx +++ b/dotcom-rendering/src/components/AudioAtom/AudioAtom.test.tsx @@ -14,7 +14,6 @@ describe('AudioAtom', () => { { { { ( ); -const buildUrl = ( - basicUrl: string, - urlWithAds: string, - shouldUseAcast?: boolean, -) => { - return shouldUseAcast ? urlWithAds : basicUrl; -}; - type Props = { id: string; trackUrl: string; kicker: string; title?: string; - shouldUseAcast?: boolean; - trackUrlWithAds: string; duration: number; }; export const AudioAtom = ({ id, trackUrl, - trackUrlWithAds, kicker, title, - shouldUseAcast, duration, }: Props): JSX.Element => { const audioEl = useRef(null); @@ -218,10 +206,6 @@ export const AudioAtom = ({ // update current time and progress bar position const [currentTime, setCurrentTime] = useState(0); const [percentPlayed, setPercentPlayed] = useState(0); - // url - const [urlToUse, setUrlToUse] = useState( - buildUrl(trackUrl, trackUrlWithAds, shouldUseAcast), - ); useEffect(() => { const audioElCurrent = audioEl.current; @@ -249,7 +233,7 @@ export const AudioAtom = ({ updateCurrentTimeAndPosition, ) : undefined; - }, [audioEl, setCurrentTime, shouldUseAcast]); + }, [audioEl, setCurrentTime]); // update duration time const [durationTime, setDurationTime] = useState(duration); @@ -305,11 +289,6 @@ export const AudioAtom = ({ return () => document.removeEventListener('keydown', keyListener); }, [audioEl, progressBarEl]); - // If Acast is enabled, replace the default url with an ad enabled one - useEffect(() => { - setUrlToUse(buildUrl(trackUrl, trackUrlWithAds, shouldUseAcast)); - }, [shouldUseAcast, trackUrl, trackUrlWithAds]); - const playAudio = () => { setIsPlaying(true); void audioEl.current?.play(); @@ -334,7 +313,7 @@ export const AudioAtom = ({ {/* eslint-disable-next-line jsx-a11y/media-has-caption -- TODO */}
diff --git a/dotcom-rendering/src/components/AudioAtomWrapper.island.tsx b/dotcom-rendering/src/components/AudioAtomWrapper.island.tsx index 55d11859b62..20fe0bd4e1b 100644 --- a/dotcom-rendering/src/components/AudioAtomWrapper.island.tsx +++ b/dotcom-rendering/src/components/AudioAtomWrapper.island.tsx @@ -39,6 +39,7 @@ export const AudioAtomWrapper = ({ // * ACast * // ***************** const [shouldUseAcast, setShouldUseAcast] = useState(false); + useEffect(() => { onConsentChange((state) => { // Should we use ad enabled audio? If so, then set the shouldUseAcast @@ -59,12 +60,10 @@ export const AudioAtomWrapper = ({ return ( ); };