diff --git a/ab-testing/config/abTests.ts b/ab-testing/config/abTests.ts
index 0b54a2036d6..9730cc14e56 100644
--- a/ab-testing/config/abTests.ts
+++ b/ab-testing/config/abTests.ts
@@ -112,7 +112,7 @@ const ABTests: ABTest[] = [
description:
"Test placing the Most Viewed and Deeply Read components in the right-hand column on the homepage.",
owners: ["fronts.and.curation@guardian.co.uk"],
- status: "OFF",
+ status: "ON",
expirationDate: `2026-04-28`,
type: "server",
audienceSize: 0 / 100,
diff --git a/dotcom-rendering/src/components/FrontSection.tsx b/dotcom-rendering/src/components/FrontSection.tsx
index 747232f9cdc..fcea812ff74 100644
--- a/dotcom-rendering/src/components/FrontSection.tsx
+++ b/dotcom-rendering/src/components/FrontSection.tsx
@@ -14,14 +14,17 @@ import type {
} from '../types/front';
import type { TagPagePagination } from '../types/tagPage';
import { isAustralianTerritory, type Territory } from '../types/territory';
+import type { TrailType } from '../types/trails';
import { AustralianTerritorySwitcher } from './AustralianTerritorySwitcher.importable';
import { BrandingLabel } from './BrandingLabel';
import { ContainerOverrides } from './ContainerOverrides';
import { ContainerTitle } from './ContainerTitle';
import { FrontPagination } from './FrontPagination';
import { FrontSectionTitle } from './FrontSectionTitle';
+import { Hide } from './Hide';
import { Island } from './Island';
import { LabsSectionHeader } from './LabsSectionHeader';
+import { MostPopularFrontRight } from './MostPopularFrontRight';
import { ShowHideButton } from './ShowHideButton';
import { ShowMore } from './ShowMore.importable';
import { Treats } from './Treats';
@@ -90,6 +93,11 @@ type Props = {
* the page skin background showing through the containers
*/
hasPageSkin?: boolean;
+ /**
+ * The Slim Homepage AB test requires some sections to have reduced width so that
+ * the Most Popular Front Right component can be placed on the right-hand side.
+ */
+ slimifySectionForAbTest?: boolean;
discussionApiUrl: string;
collectionBranding?: CollectionBranding;
isTagPage?: boolean;
@@ -98,6 +106,8 @@ type Props = {
isAboveMobileAd?: boolean;
/** Indicates whether this is a Guardian Labs container */
isLabs?: boolean;
+ mostViewed?: TrailType[];
+ deeplyRead?: TrailType[];
};
const width = (columns: number, columnWidth: number, columnGap: number) =>
@@ -356,12 +366,17 @@ const sectionControls = css`
const sectionContent = css`
margin: 0;
+ grid-column: content;
.hidden > & {
display: none;
}
+`;
- grid-column: content;
+const slimSectionContent = css`
+ ${from.wide} {
+ grid-column: 5 / 14;
+ }
`;
const sectionContentRow = (toggleable: boolean) => css`
@@ -385,7 +400,23 @@ const sectionContentBorderFromLeftCol = css`
bottom: 0;
border-left: 1px solid ${schemePalette('--section-border')};
transform: translateX(-50%);
- /** Keeps the vertical divider ontop of carousel item dividers */
+ /** Keeps the vertical divider on top of carousel item dividers */
+ z-index: 1;
+ }
+ }
+`;
+
+const slimHomepageRightBorderStyles = css`
+ ${from.wide} {
+ ::after {
+ content: '';
+ position: absolute;
+ top: ${space[2]}px;
+ bottom: 0;
+ right: 0;
+ border-right: 1px solid ${schemePalette('--section-border')};
+ transform: translateX(-50%);
+ /** Keeps the vertical divider on top of carousel item dividers */
z-index: 1;
}
}
@@ -619,6 +650,7 @@ export const FrontSection = ({
isOnPaidContentFront,
targetedTerritory,
hasPageSkin = false,
+ slimifySectionForAbTest = false,
discussionApiUrl,
collectionBranding,
isTagPage = false,
@@ -626,6 +658,8 @@ export const FrontSection = ({
isAboveDesktopAd = false,
isAboveMobileAd = false,
isLabs = false,
+ mostViewed = [],
+ deeplyRead = [],
}: Props) => {
const isToggleable = toggleable && !!sectionId;
const showVerticalRule = !hasPageSkin;
@@ -690,6 +724,15 @@ export const FrontSection = ({
title,
showSectionColours,
),
+ // To reduce the width of the border line between Features
+ // and More features in the Slim Homepage AB test.
+ slimifySectionForAbTest &&
+ sectionId === 'more-features' &&
+ css`
+ ${from.wide} {
+ grid-column: 2 / 14;
+ }
+ `,
]}
/>
)}
@@ -784,18 +827,58 @@ export const FrontSection = ({
{children}
+ {slimifySectionForAbTest && sectionId === 'news' && (
+
+
+
+
+
+ )}
+
+ {slimifySectionForAbTest && sectionId === 'features' && (
+
+
+
+
+
+ )}
+
,
+ render: (args) => (
+
+
+
+ ),
} satisfies Meta
;
export default meta;
diff --git a/dotcom-rendering/src/components/MostPopularFrontRight.tsx b/dotcom-rendering/src/components/MostPopularFrontRight.tsx
index a05da13bac3..af6e8123bbe 100644
--- a/dotcom-rendering/src/components/MostPopularFrontRight.tsx
+++ b/dotcom-rendering/src/components/MostPopularFrontRight.tsx
@@ -14,11 +14,19 @@ import { LinkHeadline } from './LinkHeadline';
const containerStyles = css`
padding-top: ${space[2]}px;
+ padding-bottom: ${space[10]}px;
display: flex;
flex-direction: column;
gap: ${space[8]}px;
`;
+const absolutePositionStyles = css`
+ position: absolute;
+ top: 0;
+ left: 0;
+ width: 300px;
+`;
+
const headingStyles = css`
padding-left: 80px;
${headlineBold24};
@@ -84,7 +92,10 @@ export const MostPopularFrontRight = ({ heading, trails }: Props) => {
return (
{heading}
diff --git a/dotcom-rendering/src/components/MostViewedFooterItem.tsx b/dotcom-rendering/src/components/MostViewedFooterItem.tsx
index 1ad8e21417e..fec931d432e 100644
--- a/dotcom-rendering/src/components/MostViewedFooterItem.tsx
+++ b/dotcom-rendering/src/components/MostViewedFooterItem.tsx
@@ -84,7 +84,7 @@ export const MostViewedFooterItem = ({
-
+
{format.design === ArticleDesign.LiveBlog ? (
{
const isHighlights = ({ collectionType }: DCRCollectionType) =>
collectionType === 'scrollable/highlights';
+const isMostPopular = ({ collectionType }: DCRCollectionType) =>
+ collectionType === 'news/most-popular';
+
const isLabs = ({ containerPalette }: DCRCollectionType) =>
containerPalette === 'Branded';
@@ -74,13 +78,25 @@ const isToggleable = (
index: number,
collection: DCRCollectionType,
isNetworkFront: boolean,
+ isInSlimHomepageAbTestVariant: boolean,
) => {
if (isNetworkFront) {
+ /**
+ * The show/hide button would be covered by the MostPopularFrontRight component
+ * in the variant of the Slim Homepage AB test.
+ */
+ const hideForSlimHomepageAbTest =
+ isInSlimHomepageAbTestVariant &&
+ (collection.displayName === 'News' ||
+ collection.displayName === 'Features' ||
+ collection.displayName === 'More features');
+
return (
collection.displayName.toLowerCase() !== 'headlines' &&
!isNavList(collection) &&
!isHighlights(collection) &&
- !isLabs(collection)
+ !isLabs(collection) &&
+ !hideForSlimHomepageAbTest
);
}
@@ -138,6 +154,23 @@ export const FrontLayout = ({ front, NAV }: Props) => {
const contributionsServiceUrl = getContributionsServiceUrl(front);
+ const abTests = useBetaAB();
+
+ /**
+ * The Slim Homepage AB test only runs on /uk and on screen widths >=1300px.
+ * In the variant of this test a Most Popular component is added to the right-hand side of the page.
+ * Page skins require slim content and is incompatible with this test. We do not run this test
+ * on pages where there is a page skin (a page skin takes precedence).
+ */
+ const isInSlimHomepageAbTestVariant =
+ (pageId === 'uk' &&
+ !hasPageSkin &&
+ abTests?.isUserInTestGroup(
+ 'fronts-and-curation-slim-homepage',
+ 'variant',
+ )) ??
+ false;
+
const fallbackAspectRatio = (collectionType: DCRContainerType) => {
switch (collectionType) {
case 'scrollable/feature':
@@ -278,6 +311,15 @@ export const FrontLayout = ({ front, NAV }: Props) => {
} | ${ophanName}`;
const mostPopularTitle = 'Most popular';
+ /**
+ * We only shrink the content of certain sections to place the Most Popular
+ * content on the right-hand side. Other sections remain full-width.
+ */
+ const isTargetedContainerInSlimHomepageAbTest =
+ collection.displayName === 'News' ||
+ collection.displayName === 'Features' ||
+ collection.displayName === 'More features';
+
if (collection.collectionType === 'scrollable/highlights') {
// Highlights are rendered in the Masthead component
return null;
@@ -352,7 +394,7 @@ export const FrontLayout = ({ front, NAV }: Props) => {
}
if (
- collection.collectionType === 'news/most-popular' &&
+ isMostPopular(collection) &&
!isPaidContent &&
switches.mostViewedFronts
) {
@@ -457,6 +499,7 @@ export const FrontLayout = ({ front, NAV }: Props) => {
index,
collection,
front.isNetworkFront,
+ isInSlimHomepageAbTestVariant,
)}
leftContent={decideLeftContent(
front,
@@ -496,6 +539,12 @@ export const FrontLayout = ({ front, NAV }: Props) => {
index,
)}
isLabs={isLabs(collection)}
+ slimifySectionForAbTest={
+ isInSlimHomepageAbTestVariant &&
+ isTargetedContainerInSlimHomepageAbTest
+ }
+ mostViewed={front.mostViewed}
+ deeplyRead={front.deeplyRead}
>