Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion ab-testing/config/abTests.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
87 changes: 85 additions & 2 deletions dotcom-rendering/src/components/FrontSection.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down Expand Up @@ -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;
Expand All @@ -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) =>
Expand Down Expand Up @@ -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`
Expand All @@ -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;
}
}
Expand Down Expand Up @@ -619,13 +650,16 @@ export const FrontSection = ({
isOnPaidContentFront,
targetedTerritory,
hasPageSkin = false,
slimifySectionForAbTest = false,
discussionApiUrl,
collectionBranding,
isTagPage = false,
hasNavigationButtons = false,
isAboveDesktopAd = false,
isAboveMobileAd = false,
isLabs = false,
mostViewed = [],
deeplyRead = [],
}: Props) => {
const isToggleable = toggleable && !!sectionId;
const showVerticalRule = !hasPageSkin;
Expand Down Expand Up @@ -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;
}
`,
]}
/>
)}
Expand Down Expand Up @@ -784,18 +827,58 @@ export const FrontSection = ({
<div
css={[
sectionContent,
slimifySectionForAbTest && slimSectionContent,
sectionContentHorizontalMargins,
sectionContentRow(toggleable),
topPadding,
showVerticalRule &&
isBetaContainer &&
sectionContentBorderFromLeftCol,
slimifySectionForAbTest &&
slimHomepageRightBorderStyles,
]}
id={`container-${sectionId}`}
>
{children}
</div>

{slimifySectionForAbTest && sectionId === 'news' && (
<div
css={css`
${from.wide} {
grid-row: content-toggleable;
grid-column: 14 / 18;
}
`}
>
<Hide when="below" breakpoint="wide">
<MostPopularFrontRight
heading="Most viewed"
trails={mostViewed}
/>
</Hide>
</div>
)}

{slimifySectionForAbTest && sectionId === 'features' && (
<div
css={css`
${from.wide} {
grid-row: content-toggleable;
grid-column: 14 / 18;
position: relative;
}
`}
>
<Hide when="below" breakpoint="wide">
<MostPopularFrontRight
heading="Deeply read"
trails={deeplyRead}
/>
</Hide>
</div>
)}

<div
css={[
sectionContentHorizontalMargins,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,11 @@ const meta = {
component: MostPopularFrontRight,
title: 'Components/MostPopularFrontRight',
decorators: [rightColumnDecorator],
render: (args) => <MostPopularFrontRight {...args} />,
render: (args) => (
<div css={{ position: 'relative' }}>
<MostPopularFrontRight {...args} />
</div>
),
} satisfies Meta<typeof MostPopularFrontRight>;

export default meta;
Expand Down
13 changes: 12 additions & 1 deletion dotcom-rendering/src/components/MostPopularFrontRight.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -84,7 +92,10 @@ export const MostPopularFrontRight = ({ heading, trails }: Props) => {
return (
<section
data-component="most-popular-front-right"
css={containerStyles}
css={[
containerStyles,
heading === 'Deeply read' && absolutePositionStyles,
]}
>
<h3 css={headingStyles}>{heading}</h3>
<ol>
Expand Down
2 changes: 1 addition & 1 deletion dotcom-rendering/src/components/MostViewedFooterItem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ export const MostViewedFooterItem = ({
<span css={bigNumber}>
<BigNumber index={position} />
</span>
<div css={[headlineHeader]}>
<div css={headlineHeader}>
<FormatBoundary format={format}>
{format.design === ArticleDesign.LiveBlog ? (
<LinkHeadline
Expand Down
53 changes: 51 additions & 2 deletions dotcom-rendering/src/layouts/FrontLayout.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import {
} from '../lib/getFrontsAdPositions';
import { hideAge } from '../lib/hideAge';
import { ophanComponentId } from '../lib/ophan-helpers';
import { useBetaAB } from '../lib/useAB';
import type { NavType } from '../model/extract-nav';
import { palette as schemePalette } from '../palette';
import type {
Expand Down Expand Up @@ -67,20 +68,35 @@ const isNavList = (collection: DCRCollectionType) => {
const isHighlights = ({ collectionType }: DCRCollectionType) =>
collectionType === 'scrollable/highlights';

const isMostPopular = ({ collectionType }: DCRCollectionType) =>
collectionType === 'news/most-popular';

const isLabs = ({ containerPalette }: DCRCollectionType) =>
containerPalette === 'Branded';

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
);
}

Expand Down Expand Up @@ -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':
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -352,7 +394,7 @@ export const FrontLayout = ({ front, NAV }: Props) => {
}

if (
collection.collectionType === 'news/most-popular' &&
isMostPopular(collection) &&
!isPaidContent &&
switches.mostViewedFronts
) {
Expand Down Expand Up @@ -457,6 +499,7 @@ export const FrontLayout = ({ front, NAV }: Props) => {
index,
collection,
front.isNetworkFront,
isInSlimHomepageAbTestVariant,
)}
leftContent={decideLeftContent(
front,
Expand Down Expand Up @@ -496,6 +539,12 @@ export const FrontLayout = ({ front, NAV }: Props) => {
index,
)}
isLabs={isLabs(collection)}
slimifySectionForAbTest={
isInSlimHomepageAbTestVariant &&
isTargetedContainerInSlimHomepageAbTest
}
mostViewed={front.mostViewed}
deeplyRead={front.deeplyRead}
>
<DecideContainer
trails={trails}
Expand Down
Loading