diff --git a/lib/ast-to-react.js b/lib/ast-to-react.js index 5248e5e1..dbb3b734 100644 --- a/lib/ast-to-react.js +++ b/lib/ast-to-react.js @@ -97,6 +97,7 @@ * @property {null|false|TransformLink} [transformLinkUri] * @property {TransformImage} [transformImageUri] * @property {TransformLinkTargetType|TransformLinkTarget} [linkTarget] + * @property {string} [linkRel] * @property {Components} [components] */ @@ -232,6 +233,10 @@ function toReact(context, node, index, parent) { typeof properties.title === 'string' ? properties.title : null ) : options.linkTarget + + properties.rel = + options.linkRel || + (properties.target === '_blank' ? 'noopener noreferrer' : undefined) } if (name === 'a' && transform) { diff --git a/lib/react-markdown.js b/lib/react-markdown.js index 92a032c7..a1545481 100644 --- a/lib/react-markdown.js +++ b/lib/react-markdown.js @@ -179,6 +179,7 @@ ReactMarkdown.propTypes = { includeElementIndex: PropTypes.bool, transformLinkUri: PropTypes.oneOfType([PropTypes.func, PropTypes.bool]), linkTarget: PropTypes.oneOfType([PropTypes.func, PropTypes.string]), + linkRel: PropTypes.string, transformImageUri: PropTypes.func, components: PropTypes.object } diff --git a/readme.md b/readme.md index 2b00a70e..8ac65d02 100644 --- a/readme.md +++ b/readme.md @@ -205,6 +205,9 @@ The default export is `ReactMarkdown`. `unwrapDisallowed` the element itself is replaced by its children * `linkTarget` (`string` or `(href, children, title) => string`, optional)\ target to use on links (such as `_blank` for ` string`, default: [`uriTransformer`][uri-transformer], optional)\ change URLs on links, pass `null` to allow all URLs, see [security][] @@ -634,6 +637,8 @@ Optionally, components will also receive: — see `includeElementIndex` option * `target` on `a` (`string`) — see `linkTarget` option +* `rel` on `a` (`string`) + — see `linkRel` option ## Security diff --git a/test/test.jsx b/test/test.jsx index aef80589..9b9ac050 100644 --- a/test/test.jsx +++ b/test/test.jsx @@ -236,7 +236,27 @@ test('should use target attribute for links if specified', () => { const actual = asHtml() assert.equal( actual, - '

This is a link to Espen.Codes.

' + '

This is a link to Espen.Codes.

' + ) +}) + +test('should use custom default rel attribute for links if specified, when target is _blank', () => { + const input = 'This is [a link](https://espen.codes/) to Espen.Codes.' + const actual = asHtml( + + ) + assert.equal( + actual, + '

This is a link to Espen.Codes.

' + ) +}) + +test('should not use default rel attribute for links if specified, when target is not _blank', () => { + const input = 'This is [a link](https://espen.codes/) to Espen.Codes.' + const actual = asHtml() + assert.equal( + actual, + '

This is a link to Espen.Codes.

' ) }) @@ -250,7 +270,7 @@ test('should call function to get target attribute for links if specified', () = ) assert.equal( actual, - '

This is a link to Espen.Codes.

' + '

This is a link to Espen.Codes.

' ) })