11import { css } from '@emotion/react' ;
22import { isNonNullable } from '@guardian/libs' ;
33import { ArticleDesign , type ArticleFormat } from '../lib/articleFormat' ;
4- import { decideTrail } from '../lib/decideTrail' ;
4+ import { decideTrail , dedupeTrail } from '../lib/decideTrail' ;
55import { useApi } from '../lib/useApi' ;
66import { addDiscussionIds } from '../lib/useCommentCount' ;
77import { palette } from '../palette' ;
@@ -20,6 +20,7 @@ type Props = {
2020 absoluteServerTimes : boolean ;
2121 renderingTarget : RenderingTarget ;
2222 isAdFreeUser : boolean ;
23+ articleURL : string ;
2324} ;
2425
2526type OnwardsResponse = {
@@ -40,9 +41,11 @@ const buildTrails = (
4041 trails : FETrailType [ ] ,
4142 trailLimit : number ,
4243 isAdFreeUser : boolean ,
44+ articleURL : string ,
4345) : TrailType [ ] => {
4446 return trails
4547 . filter ( ( trailType ) => ! ( isTrailPaidContent ( trailType ) && isAdFreeUser ) )
48+ . filter ( ( trailType ) => dedupeTrail ( trailType , articleURL ) )
4649 . slice ( 0 , trailLimit )
4750 . map ( decideTrail ) ;
4851} ;
@@ -56,6 +59,7 @@ export const FetchOnwardsData = ({
5659 absoluteServerTimes,
5760 renderingTarget,
5861 isAdFreeUser,
62+ articleURL,
5963} : Props ) => {
6064 const { data, error } = useApi < OnwardsResponse > ( url ) ;
6165
@@ -81,11 +85,13 @@ export const FetchOnwardsData = ({
8185 . filter ( isNonNullable ) ,
8286 ) ;
8387
88+ const trails = buildTrails ( data . trails , limit , isAdFreeUser , articleURL ) ;
89+
8490 return (
8591 < div css = { minHeight } >
8692 < Carousel
8793 heading = { data . heading || data . displayname } // Sometimes the api returns heading as 'displayName'
88- trails = { buildTrails ( data . trails , limit , isAdFreeUser ) }
94+ trails = { trails }
8995 description = { data . description }
9096 onwardsSource = { onwardsSource }
9197 format = { format }
0 commit comments