diff --git a/dotcom-rendering/src/components/EnhanceAffiliateLinks.importable.tsx b/dotcom-rendering/src/components/EnhanceAffiliateLinks.importable.tsx
index 40e3cc5ac37..f443f1f4bf0 100644
--- a/dotcom-rendering/src/components/EnhanceAffiliateLinks.importable.tsx
+++ b/dotcom-rendering/src/components/EnhanceAffiliateLinks.importable.tsx
@@ -1,10 +1,12 @@
import { useEffect } from 'react';
import { getSkimlinksAccountId, isSkimlink } from '../lib/affiliateLinksUtils';
+import { useBetaAB } from '../lib/useAB';
/**
* Add custom parameters to skimlink URLs:
- * - referrer
+ * - Referrer
* - Skimlinks account ID
+ * - AB test participations
*
* ## Why does this need to be an Island?
*
@@ -15,6 +17,18 @@ import { getSkimlinksAccountId, isSkimlink } from '../lib/affiliateLinksUtils';
* (No visual story exists as this does not render anything)
*/
export const EnhanceAffiliateLinks = () => {
+ const abTests = useBetaAB();
+
+ // Get users server/client-side AB test participations
+ const abTestParticipations = abTests?.getParticipations();
+
+ // Reduce abTestParticipations to a comma-separated string
+ const abTestString = abTestParticipations
+ ? Object.entries(abTestParticipations)
+ .map(([key, value]) => `${key}:${value}`)
+ .join(',')
+ : '';
+
useEffect(() => {
const allLinksOnPage = [...document.querySelectorAll('a')];
@@ -28,7 +42,9 @@ export const EnhanceAffiliateLinks = () => {
const skimlinksAccountId = getSkimlinksAccountId(link.href);
// Skimlinks treats xcust as one long string, so we use | to separate values
- const xcustValue = `referrer|${referrerDomain}|accountId|${skimlinksAccountId}`;
+ const xcustValue = `referrer|${referrerDomain}|accountId|${skimlinksAccountId}${
+ abTestString ? `|abTestParticipations|${abTestString}` : ''
+ }`;
link.href = `${link.href}&xcust=${encodeURIComponent(
xcustValue,
diff --git a/dotcom-rendering/src/components/EnhanceAffiliateLinks.test.tsx b/dotcom-rendering/src/components/EnhanceAffiliateLinks.test.tsx
new file mode 100644
index 00000000000..cb74d50bdc1
--- /dev/null
+++ b/dotcom-rendering/src/components/EnhanceAffiliateLinks.test.tsx
@@ -0,0 +1,84 @@
+import '@testing-library/jest-dom';
+import { render } from '@testing-library/react';
+import { useBetaAB } from '../lib/useAB';
+import { EnhanceAffiliateLinks } from './EnhanceAffiliateLinks.importable';
+
+// Mock the useAB module
+jest.mock('../lib/useAB', () => ({
+ useBetaAB: jest.fn(),
+}));
+
+describe('EnhanceAffiliateLinks', () => {
+ beforeEach(() => {
+ // Clear the DOM before each test
+ document.body.innerHTML = '';
+ jest.restoreAllMocks();
+ });
+
+ it('should not modify links if no Skimlinks are present', () => {
+ document.body.innerHTML = `
+ Not a Skimlink
+ `;
+
+ render();
+
+ const link = document.querySelector('a');
+ expect(link?.href).toBe('https://example.com/');
+ });
+
+ it('should append xcust parameter to Skimlinks with refferer set to none if unavailable', () => {
+ Object.defineProperty(document, 'referrer', {
+ value: '',
+ configurable: true,
+ });
+
+ document.body.innerHTML = `
+ Skimlink
+ `;
+
+ render();
+
+ const link = document.querySelector('a');
+ expect(link?.href).toContain(
+ 'xcust=referrer%7Cnone%7CaccountId%7C12345',
+ );
+ });
+
+ it('should append xcust parameter to Skimlinks with refferer set if available', () => {
+ Object.defineProperty(document, 'referrer', {
+ value: 'https://foo.com',
+ configurable: true,
+ });
+
+ document.body.innerHTML = `
+ Skimlink
+ `;
+
+ render();
+
+ const link = document.querySelector('a');
+ expect(link?.href).toContain(
+ 'xcust=referrer%7Cfoo.com%7CaccountId%7C12345',
+ );
+ });
+
+ it('should include AB test participations in xcust if present', () => {
+ document.body.innerHTML = `
+ Skimlink
+ `;
+
+ (useBetaAB as jest.Mock).mockReturnValue({
+ getParticipations: () => ({
+ test1: 'variantA',
+ test2: 'variantB',
+ }),
+ });
+
+ render();
+
+ const link = document.querySelector('a');
+ expect(link?.href).toContain(
+ 'xcust=referrer%7Cfoo.com%7CaccountId%7C12345%7CabTestParticipations%7Ctest1%3AvariantA%2Ctest2%3AvariantB',
+ );
+ });
+});