diff --git a/utils/markdown/index.test.js b/utils/markdown/index.test.js
index 6adca2e68e64..a309968b077a 100644
--- a/utils/markdown/index.test.js
+++ b/utils/markdown/index.test.js
@@ -144,6 +144,12 @@ this is long text this is long text this is long text this is long text this is
expect(output).toContain('internal_link');
});
+ test(' should contain target=_blank for internal links that live under /plugins', () => {
+ const output = format('[internal_link](http://localhost/plugins/example)', {siteURL: 'http://localhost'});
+
+ expect(output).toContain('internal_link');
+ });
+
test(' should not contain target=_blank for pl|channels|messages links', () => {
const pl = format('[thread](/reiciendis-0/pl/b3hrs3brjjn7fk4kge3xmeuffc))', {siteURL: 'http://localhost'});
expect(pl).toContain('thread');
@@ -153,5 +159,8 @@ this is long text this is long text this is long text this is long text this is
const messages = format('[thread](/reiciendis-0/messages/b3hrs3brjjn7fk4kge3xmeuffc))', {siteURL: 'http://localhost'});
expect(messages).toContain('thread');
+
+ const plugin = format('[plugin](/reiciendis-0/plugins/example))', {siteURL: 'http://localhost'});
+ expect(plugin).toContain('plugin');
});
});
diff --git a/utils/markdown/renderer.tsx b/utils/markdown/renderer.tsx
index ee982115380f..dce48c27741c 100644
--- a/utils/markdown/renderer.tsx
+++ b/utils/markdown/renderer.tsx
@@ -207,14 +207,17 @@ export default class Renderer extends marked.Renderer {
output += `" href="${outHref}" rel="noreferrer"`;
- // Any link that begins with siteURL should be opened inside the app
- let internalLink = outHref.startsWith(this.formattingOptions.siteURL || '');
+ const pluginURL = `${this.formattingOptions.siteURL}/plugins`;
+
+ // Any link that begins with siteURL should be opened inside the app, except when rooted
+ // at /plugins, which is logically "outside the app" despite being hosted by a plugin.
+ let internalLink = outHref.startsWith(this.formattingOptions.siteURL || '') && (!outHref.startsWith(pluginURL));
// special case for team invite links, channel links, and permalinks that are inside the app
const pattern = new RegExp(
'^(' +
TextFormatting.escapeRegex(this.formattingOptions.siteURL) +
- ')?\\/(?:signup_user_complete|admin_console|[^\\/]+\\/(?:pl|channels|messages))\\/',
+ ')?\\/(?:signup_user_complete|admin_console|[^\\/]+\\/(?:pl|channels|messages|plugins))\\/',
);
internalLink = internalLink || pattern.test(outHref);