diff --git a/dotcom-rendering/src/components/AffiliateDisclaimer.importable.tsx b/dotcom-rendering/src/components/AffiliateDisclaimer.importable.tsx
new file mode 100644
index 00000000000..86d3c495fba
--- /dev/null
+++ b/dotcom-rendering/src/components/AffiliateDisclaimer.importable.tsx
@@ -0,0 +1,35 @@
+import { css } from '@emotion/react';
+import { space, textSans15 } from '@guardian/source/foundations';
+import { Hide } from '@guardian/source/react-components';
+import {
+ DisclaimerText,
+ useAffiliateDisclaimerEvent,
+} from '../lib/affiliateDisclaimerHelpers';
+
+const disclaimerLeftColStyles = css`
+ ${textSans15};
+ /**
+ * Typography preset styles should not be overridden.
+ * This has been done because the styles do not directly map to the new presets.
+ * Please speak to your team's designer and update this to use a more appropriate preset.
+ */
+ line-height: 1.15;
+ padding-top: ${space[1]}px;
+ padding-bottom: ${space[1]}px;
+`;
+
+const AffiliateDisclaimer = () => {
+ useAffiliateDisclaimerEvent();
+ return (
+
+
+
+ );
+};
+
+export { AffiliateDisclaimer };
diff --git a/dotcom-rendering/src/components/AffiliateDisclaimer.tsx b/dotcom-rendering/src/components/AffiliateDisclaimer.tsx
deleted file mode 100644
index 712ebf8d575..00000000000
--- a/dotcom-rendering/src/components/AffiliateDisclaimer.tsx
+++ /dev/null
@@ -1,113 +0,0 @@
-import { css } from '@emotion/react';
-import {
- palette,
- space,
- textSans12,
- textSans14,
- textSans15,
-} from '@guardian/source/foundations';
-import { Hide } from '@guardian/source/react-components';
-import { palette as themePalette } from '../palette';
-
-const disclaimerLeftColStyles = css`
- ${textSans15};
- /**
- * Typography preset styles should not be overridden.
- * This has been done because the styles do not directly map to the new presets.
- * Please speak to your team's designer and update this to use a more appropriate preset.
- */
- line-height: 1.15;
- padding-top: ${space[1]}px;
- padding-bottom: ${space[1]}px;
-`;
-
-const galleryDisclaimerStyles = css`
- ${textSans12};
- line-height: 1.5;
- color: ${themePalette('--affiliate-disclaimer-text')};
- a {
- color: ${themePalette('--affiliate-disclaimer-text')};
- transition: border-color 0.15s ease-out;
- border-bottom: 1px solid ${palette.neutral[46]};
- text-decoration: none;
- }
- a:hover {
- border-bottom: 1px solid
- ${themePalette('--affiliate-disclaimer-text-hover')};
- text-decoration: none;
- }
-`;
-
-const disclaimerInlineStyles = css`
- ${textSans14};
- /**
- * Typography preset styles should not be overridden.
- * This has been done because the styles do not directly map to the new presets.
- * Please speak to your team's designer and update this to use a more appropriate preset.
- */
- line-height: 1.15;
- float: left;
- clear: left;
- width: 8.75rem;
- background-color: ${themePalette('--affiliate-disclaimer-background')};
- :hover {
- background-color: ${themePalette(
- '--affiliate-disclaimer-background-hover',
- )};
- }
- margin-top: ${space[1]}px;
- margin-right: ${space[5]}px;
- margin-bottom: ${space[1]}px;
- padding-top: ${space[0]}px;
- padding-right: 5px;
- padding-left: 5px;
- padding-bottom: ${space[3]}px;
-`;
-
-const DisclaimerText = () => (
-
- The Guardian’s journalism is independent. We will earn a commission if
- you buy something through an affiliate link.
-
- Learn more
-
- .
-
-);
-
-const AffiliateDisclaimer = () => (
-
-
-
-);
-
-const AffiliateDisclaimerInline = () => (
-
-
-
-);
-
-const GalleryAffiliateDisclaimer = () => (
-
-);
-
-export {
- AffiliateDisclaimer,
- AffiliateDisclaimerInline,
- GalleryAffiliateDisclaimer,
-};
diff --git a/dotcom-rendering/src/components/AffiliateDisclaimerInline.importable.tsx b/dotcom-rendering/src/components/AffiliateDisclaimerInline.importable.tsx
new file mode 100644
index 00000000000..cadd1e0036d
--- /dev/null
+++ b/dotcom-rendering/src/components/AffiliateDisclaimerInline.importable.tsx
@@ -0,0 +1,50 @@
+import { css } from '@emotion/react';
+import { space, textSans14 } from '@guardian/source/foundations';
+import { Hide } from '@guardian/source/react-components';
+import {
+ DisclaimerText,
+ useAffiliateDisclaimerEvent,
+} from '../lib/affiliateDisclaimerHelpers';
+import { palette as themePalette } from '../palette';
+
+const disclaimerInlineStyles = css`
+ ${textSans14};
+ /**
+ * Typography preset styles should not be overridden.
+ * This has been done because the styles do not directly map to the new presets.
+ * Please speak to your team's designer and update this to use a more appropriate preset.
+ */
+ line-height: 1.15;
+ float: left;
+ clear: left;
+ width: 8.75rem;
+ background-color: ${themePalette('--affiliate-disclaimer-background')};
+ :hover {
+ background-color: ${themePalette(
+ '--affiliate-disclaimer-background-hover',
+ )};
+ }
+ margin-top: ${space[1]}px;
+ margin-right: ${space[5]}px;
+ margin-bottom: ${space[1]}px;
+ padding-top: ${space[0]}px;
+ padding-right: 5px;
+ padding-left: 5px;
+ padding-bottom: ${space[3]}px;
+`;
+
+const AffiliateDisclaimerInline = () => {
+ useAffiliateDisclaimerEvent();
+ return (
+
+
+
+ );
+};
+
+export { AffiliateDisclaimerInline };
diff --git a/dotcom-rendering/src/components/GalleryAffiliateDisclaimer.importable.tsx b/dotcom-rendering/src/components/GalleryAffiliateDisclaimer.importable.tsx
new file mode 100644
index 00000000000..4a7d02592f2
--- /dev/null
+++ b/dotcom-rendering/src/components/GalleryAffiliateDisclaimer.importable.tsx
@@ -0,0 +1,55 @@
+import { css } from '@emotion/react';
+import {
+ palette,
+ space,
+ textSans12,
+ textSans15,
+} from '@guardian/source/foundations';
+import {
+ DisclaimerText,
+ useAffiliateDisclaimerEvent,
+} from '../lib/affiliateDisclaimerHelpers';
+import { palette as themePalette } from '../palette';
+
+const disclaimerLeftColStyles = css`
+ ${textSans15};
+ /**
+ * Typography preset styles should not be overridden.
+ * This has been done because the styles do not directly map to the new presets.
+ * Please speak to your team's designer and update this to use a more appropriate preset.
+ */
+ line-height: 1.15;
+ padding-top: ${space[1]}px;
+ padding-bottom: ${space[1]}px;
+`;
+
+const galleryDisclaimerStyles = css`
+ ${textSans12};
+ line-height: 1.5;
+ color: ${themePalette('--affiliate-disclaimer-text')};
+ a {
+ color: ${themePalette('--affiliate-disclaimer-text')};
+ transition: border-color 0.15s ease-out;
+ border-bottom: 1px solid ${palette.neutral[46]};
+ text-decoration: none;
+ }
+ a:hover {
+ border-bottom: 1px solid
+ ${themePalette('--affiliate-disclaimer-text-hover')};
+ text-decoration: none;
+ }
+`;
+
+const GalleryAffiliateDisclaimer = () => {
+ useAffiliateDisclaimerEvent();
+ return (
+
+ );
+};
+
+export { GalleryAffiliateDisclaimer };
diff --git a/dotcom-rendering/src/layouts/AudioLayout.tsx b/dotcom-rendering/src/layouts/AudioLayout.tsx
index d4327da1612..5dda91e83a5 100644
--- a/dotcom-rendering/src/layouts/AudioLayout.tsx
+++ b/dotcom-rendering/src/layouts/AudioLayout.tsx
@@ -7,7 +7,7 @@ import {
} from '@guardian/source/foundations';
import { StraightLines } from '@guardian/source-development-kitchen/react-components';
import { AdSlot, MobileStickyContainer } from '../components/AdSlot.web';
-import { AffiliateDisclaimer } from '../components/AffiliateDisclaimer';
+import { AffiliateDisclaimer } from '../components/AffiliateDisclaimer.importable';
import { ArticleBody } from '../components/ArticleBody';
import { ArticleContainer } from '../components/ArticleContainer';
import { ArticleHeadline } from '../components/ArticleHeadline';
@@ -272,7 +272,12 @@ export const AudioLayout = (props: WebProps) => {
}
/>
{!!article.affiliateLinksDisclaimer && (
-
+
+
+
)}
diff --git a/dotcom-rendering/src/layouts/GalleryLayout.tsx b/dotcom-rendering/src/layouts/GalleryLayout.tsx
index a2b6480b472..84595e53d7a 100644
--- a/dotcom-rendering/src/layouts/GalleryLayout.tsx
+++ b/dotcom-rendering/src/layouts/GalleryLayout.tsx
@@ -9,7 +9,6 @@ import { Hide } from '@guardian/source/react-components';
import { AdPlaceholder } from '../components/AdPlaceholder.apps';
import { AdPortals } from '../components/AdPortals.importable';
import { AdSlot } from '../components/AdSlot.web';
-import { GalleryAffiliateDisclaimer } from '../components/AffiliateDisclaimer';
import { AppsFooter } from '../components/AppsFooter.importable';
import { ArticleHeadline } from '../components/ArticleHeadline';
import { ArticleMetaApps } from '../components/ArticleMeta.apps';
@@ -20,6 +19,7 @@ import { DiscussionLayout } from '../components/DiscussionLayout';
import { FetchMoreGalleriesData } from '../components/FetchMoreGalleriesData.importable';
import { Footer } from '../components/Footer';
import { DesktopAdSlot, MobileAdSlot } from '../components/GalleryAdSlots';
+import { GalleryAffiliateDisclaimer } from '../components/GalleryAffiliateDisclaimer.importable';
import { GalleryImage } from '../components/GalleryImage';
import { HeaderAdSlot } from '../components/HeaderAdSlot';
import { Island } from '../components/Island';
@@ -496,7 +496,9 @@ const Meta = ({
/>
) : null}
{!!frontendData.affiliateLinksDisclaimer && (
-
+
+
+
)}
);
diff --git a/dotcom-rendering/src/layouts/ImmersiveLayout.tsx b/dotcom-rendering/src/layouts/ImmersiveLayout.tsx
index efdca55a82e..1bf04054dba 100644
--- a/dotcom-rendering/src/layouts/ImmersiveLayout.tsx
+++ b/dotcom-rendering/src/layouts/ImmersiveLayout.tsx
@@ -9,7 +9,7 @@ import {
import { StraightLines } from '@guardian/source-development-kitchen/react-components';
import { AdPortals } from '../components/AdPortals.importable';
import { AdSlot, MobileStickyContainer } from '../components/AdSlot.web';
-import { AffiliateDisclaimer } from '../components/AffiliateDisclaimer';
+import { AffiliateDisclaimer } from '../components/AffiliateDisclaimer.importable';
import { AppsFooter } from '../components/AppsFooter.importable';
import { ArticleBody } from '../components/ArticleBody';
import { ArticleContainer } from '../components/ArticleContainer';
@@ -613,7 +613,12 @@ export const ImmersiveLayout = (props: WebProps | AppProps) => {
}
/>
{!!article.affiliateLinksDisclaimer && (
-
+
+
+
)}
>
@@ -643,7 +648,12 @@ export const ImmersiveLayout = (props: WebProps | AppProps) => {
}
/>
{!!article.affiliateLinksDisclaimer && (
-
+
+
+
)}
>
)}
diff --git a/dotcom-rendering/src/layouts/ShowcaseLayout.tsx b/dotcom-rendering/src/layouts/ShowcaseLayout.tsx
index 4fc3ddd4119..cba2b0cf52a 100644
--- a/dotcom-rendering/src/layouts/ShowcaseLayout.tsx
+++ b/dotcom-rendering/src/layouts/ShowcaseLayout.tsx
@@ -9,7 +9,7 @@ import { Hide } from '@guardian/source/react-components';
import { StraightLines } from '@guardian/source-development-kitchen/react-components';
import { AdPortals } from '../components/AdPortals.importable';
import { AdSlot, MobileStickyContainer } from '../components/AdSlot.web';
-import { AffiliateDisclaimer } from '../components/AffiliateDisclaimer';
+import { AffiliateDisclaimer } from '../components/AffiliateDisclaimer.importable';
import { AppsFooter } from '../components/AppsFooter.importable';
import { ArticleBody } from '../components/ArticleBody';
import { ArticleContainer } from '../components/ArticleContainer';
@@ -490,7 +490,12 @@ export const ShowcaseLayout = (props: WebProps | AppsProps) => {
}
/>
{!!article.affiliateLinksDisclaimer && (
-
+
+
+
)}
>
@@ -520,7 +525,12 @@ export const ShowcaseLayout = (props: WebProps | AppsProps) => {
}
/>
{!!article.affiliateLinksDisclaimer && (
-
+
+
+
)}
>
)}
diff --git a/dotcom-rendering/src/layouts/StandardLayout.tsx b/dotcom-rendering/src/layouts/StandardLayout.tsx
index 7510c627882..91f99959bc7 100644
--- a/dotcom-rendering/src/layouts/StandardLayout.tsx
+++ b/dotcom-rendering/src/layouts/StandardLayout.tsx
@@ -9,7 +9,7 @@ import { Hide } from '@guardian/source/react-components';
import { StraightLines } from '@guardian/source-development-kitchen/react-components';
import { AdPortals } from '../components/AdPortals.importable';
import { AdSlot, MobileStickyContainer } from '../components/AdSlot.web';
-import { AffiliateDisclaimer } from '../components/AffiliateDisclaimer';
+import { AffiliateDisclaimer } from '../components/AffiliateDisclaimer.importable';
import { AppsEpic } from '../components/AppsEpic.importable';
import { AppsFooter } from '../components/AppsFooter.importable';
import { ArticleBody } from '../components/ArticleBody';
@@ -652,7 +652,12 @@ export const StandardLayout = (props: WebProps | AppProps) => {
/>
{!!article.affiliateLinksDisclaimer && (
-
+
+
+
)}
>
@@ -682,7 +687,12 @@ export const StandardLayout = (props: WebProps | AppProps) => {
}
/>
{!!article.affiliateLinksDisclaimer && (
-
+
+
+
)}
)}
diff --git a/dotcom-rendering/src/lib/affiliateDisclaimerHelpers.tsx b/dotcom-rendering/src/lib/affiliateDisclaimerHelpers.tsx
new file mode 100644
index 00000000000..93a9aff5b9a
--- /dev/null
+++ b/dotcom-rendering/src/lib/affiliateDisclaimerHelpers.tsx
@@ -0,0 +1,43 @@
+import { useEffect } from 'react';
+import { submitComponentEvent } from '../client/ophan/ophan';
+
+/**
+ * On Articles we render multiple Affiliate Disclaimer components,
+ * For example one in the left column (for non-mobile breakpoints)
+ * and one inline (for mobile breakpoints), however we don't want to
+ * trigger multiple detect events, eg. one event per component,
+ * one event per Article is desired, we're therefore keeping a record
+ * of the event being tracked here to achieve this.
+ */
+let affiliateDisclaimerDetectTracked = false;
+
+const useAffiliateDisclaimerEvent = (): void => {
+ useEffect(() => {
+ if (!affiliateDisclaimerDetectTracked) {
+ void submitComponentEvent(
+ {
+ action: 'DETECT',
+ component: {
+ componentType: 'AFFILIATE_DISCLAIMER',
+ },
+ },
+ 'Web',
+ );
+
+ affiliateDisclaimerDetectTracked = true;
+ }
+ }, []);
+};
+
+const DisclaimerText = () => (
+
+ The Guardian’s journalism is independent. We will earn a commission if
+ you buy something through an affiliate link.
+
+ Learn more
+
+ .
+
+);
+
+export { DisclaimerText, useAffiliateDisclaimerEvent };
diff --git a/dotcom-rendering/src/lib/renderElement.tsx b/dotcom-rendering/src/lib/renderElement.tsx
index 22132e9ed21..3df1a7335d4 100644
--- a/dotcom-rendering/src/lib/renderElement.tsx
+++ b/dotcom-rendering/src/lib/renderElement.tsx
@@ -1,5 +1,5 @@
import { AdPlaceholder } from '../components/AdPlaceholder.apps';
-import { AffiliateDisclaimerInline } from '../components/AffiliateDisclaimer';
+import { AffiliateDisclaimerInline } from '../components/AffiliateDisclaimerInline.importable';
import { AudioAtomWrapper } from '../components/AudioAtomWrapper.importable';
import { BlockquoteBlockComponent } from '../components/BlockquoteBlockComponent';
import { CalloutBlockComponent } from '../components/CalloutBlockComponent.importable';
@@ -961,7 +961,11 @@ export const renderElement = ({
);
case 'model.dotcomrendering.pageElements.DisclaimerBlockElement': {
- return ;
+ return (
+
+
+
+ );
}
case 'model.dotcomrendering.pageElements.CrosswordElement':
return (