Skip to content

Commit 952f363

Browse files
fix: [UIE-10352] Added capability to open links in markdown in different tab (#13501)
* fix: [UIE-10352] Added capability to open links in markdown in different tab * fix: [UIE-10352] added changeset
1 parent bbd6995 commit 952f363

File tree

3 files changed

+40
-3
lines changed

3 files changed

+40
-3
lines changed
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@linode/manager": Fixed
3+
---
4+
5+
Product content received in markdown format can have links. Added capability in markdown to open these links in new tab ([#13501](https://github.com/linode/manager/pull/13501))

packages/manager/src/components/Markdown/Markdown.tsx

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import type { SanitizeOptions } from 'src/utilities/sanitizeHTML';
1010

1111
export interface HighlightedMarkdownProps {
1212
className?: string;
13+
openLinksInNewTab?: boolean;
1314
sanitizeOptions?: SanitizeOptions;
1415
textOrMarkdown: string;
1516
}
@@ -20,7 +21,8 @@ export interface HighlightedMarkdownProps {
2021
* - Will perform syntax highlighting on any fenced code blocks
2122
*/
2223
export const Markdown = (props: HighlightedMarkdownProps) => {
23-
const { className, sanitizeOptions, textOrMarkdown } = props;
24+
const { className, openLinksInNewTab, sanitizeOptions, textOrMarkdown } =
25+
props;
2426

2527
const theme = useTheme();
2628

@@ -36,7 +38,7 @@ export const Markdown = (props: HighlightedMarkdownProps) => {
3638
lang,
3739
theme: getHighlighterTheme(theme.palette.mode),
3840
});
39-
} catch (error) {
41+
} catch {
4042
return shiki.codeToHtml(str, {
4143
lang: 'js',
4244
theme: getHighlighterTheme(theme.palette.mode),
@@ -48,6 +50,28 @@ export const Markdown = (props: HighlightedMarkdownProps) => {
4850
linkify: true,
4951
});
5052

53+
if (openLinksInNewTab) {
54+
const defaultRender =
55+
unsafeMarkdownIt.renderer.rules.link_open ||
56+
function (tokens, idx, options, env, self) {
57+
return self.renderToken(tokens, idx, options);
58+
};
59+
60+
unsafeMarkdownIt.renderer.rules.link_open = function (
61+
tokens,
62+
idx,
63+
options,
64+
env,
65+
self
66+
) {
67+
tokens[idx].attrSet('target', '_blank');
68+
// Adding rel="noopener noreferrer" directly here just as backup,
69+
// although sanitizeHTML will already add it when it sees target="_blank"
70+
tokens[idx].attrSet('rel', 'noopener noreferrer');
71+
return defaultRender(tokens, idx, options, env, self);
72+
};
73+
}
74+
5175
const unsafeParsedMarkdown = unsafeMarkdownIt.render(textOrMarkdown);
5276

5377
const sanitizedHtml = sanitizeHTML({

packages/manager/src/features/Marketplace/ProductDetails/ProductDetailsTabs.tsx

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,16 @@ const MarkdownContentRenderer = ({ content }: { content: string }) => {
3838
return (
3939
<StyledTabContent>
4040
<Markdown
41+
openLinksInNewTab
4142
sanitizeOptions={{
42-
ALLOWED_ATTR: [...allowedHTMLAttr, 'target', 'src', 'alt', 'style'],
43+
ALLOWED_ATTR: [
44+
...allowedHTMLAttr,
45+
'target',
46+
'rel',
47+
'src',
48+
'alt',
49+
'style',
50+
],
4351
ALLOWED_TAGS: [...allowedHTMLTagsFlexible, 'img'],
4452
}}
4553
textOrMarkdown={content}

0 commit comments

Comments
 (0)