@@ -2,6 +2,7 @@ import { css } from '@emotion/react';
2
2
import { headlineMedium17 , space } from '@guardian/source/foundations' ;
3
3
import { type ReactNode } from 'react' ;
4
4
import sanitise , { type IOptions } from 'sanitize-html' ;
5
+ import { isSkimlink } from '../lib/affiliateLinksUtils' ;
5
6
import { getAttrs , parseHtml } from '../lib/domUtils' ;
6
7
import { palette } from '../palette' ;
7
8
@@ -38,6 +39,7 @@ const renderTextElement = (node: Node, key: number): ReactNode => {
38
39
return text === '' ? null : < em key = { key } > { children } </ em > ;
39
40
case 'A' : {
40
41
const attrs = getAttrs ( node ) ;
42
+ const href = attrs ?. getNamedItem ( 'href' ) ?. value ;
41
43
42
44
return (
43
45
< a
@@ -51,7 +53,7 @@ const renderTextElement = (node: Node, key: number): ReactNode => {
51
53
${ palette ( '--article-link-border-hover' ) } ;
52
54
}
53
55
` }
54
- href = { attrs ?. getNamedItem ( ' href' ) ?. value }
56
+ href = { href }
55
57
target = { attrs ?. getNamedItem ( 'target' ) ?. value }
56
58
data-link-name = {
57
59
attrs ?. getNamedItem ( 'data-link-name' ) ?. value
@@ -60,6 +62,15 @@ const renderTextElement = (node: Node, key: number): ReactNode => {
60
62
attrs ?. getNamedItem ( 'data-component' ) ?. value
61
63
}
62
64
key = { key }
65
+ /**
66
+ * Affiliate links must have the rel attribute set to "sponsored"
67
+ * @see https://developers.google.com/search/docs/crawling-indexing/qualify-outbound-links
68
+ */
69
+ rel = {
70
+ isSkimlink ( href )
71
+ ? 'sponsored'
72
+ : getAttrs ( node ) ?. getNamedItem ( 'rel' ) ?. value
73
+ }
63
74
>
64
75
{ children }
65
76
</ a >
0 commit comments