Hello,
First of all this component help us a lot. Thank you for that.
Today, we started to work on a new project and we are redering links in this component. We noticed that when identifies a link it creates an <a> tag, this is fine. But we need to open it in a new tab. So, as a sugestion, could you guys update this behavior? I think it will improve the component.
We fixed this in our side, if you guys are interested let us know.
Thanks a lot.
Hi Bruno,
As a quick workaround for this kind of problem, you can also insert html instead of Markdown text.
So if you use the text:
... it should open the link in a new tab.
About updating the markdown component for this, I see there are different syntaxes possible for this. What would be your preference? And how did you fix it on your side?Thank you
We change in the component:
- ConvertAndSetContainerHTML screen action
- JavaScript the "replaceContent()", we identify a link and build it with "_blank" parameter setted.
Not sure what is the best way to go with that, but that was our change. Please let me know your thoughts.
Thanks.
Yes, that will work if you want all the links to open in new tabs. I'll check what is the most popular or easiest way to specify this in markdown syntax. Then I'll add this in the conversion, probably using the same solution like you did, but at least it will be something we can activate/deactivate for each link using markdown syntax.
Hi everyone,
While post-processing the rendered HTML or manually replacing DOM strings via custom scripts (like doing replaceContent post-render) gets the job done, it can cause performance overhead and layout thrashing in Reactive/Web applications.
There is actually a native, secure, and highly performant way to handle this by hooking directly into the marked.js library's custom Renderer configuration before the HTML is even painted in the DOM.
Additionally, when forcing links to open in a new tab (target="_blank"), it is a critical security best practice to inject rel="noopener noreferrer". This prevents a vulnerability known as Reverse Tabnabbing, where a malicious linked page could gain partial control over your parent application's window.
Here is the native implementation you can use inside your OutSystems JavaScript node.
1. Add a Block Configuration (Optional but Recommended)
Create an input parameter on your Markdown block:
Name: OpenLinksInNewTab (Boolean)
Default: True
Description: If true, links open in a new tab safely.
2. The JavaScript Node Implementation
Pass your ContainerId (Text), MarkdownText (Text), and OpenLinksInNewTab (Boolean) into your JS node, and replace the rendering logic with this:======================================================================================================================================================================
// 1. Locate the target HTML container
const target = document.getElementById($parameters.ContainerId);
if (target) {
// 2. Clean input and handle empty state immediately
const cleanText = ($parameters.MarkdownText || '').trim();
if (!cleanText) {
target.innerHTML = '';
return;
}
// 3. Ensure the MarkedJS library is loaded in the global scope
if (typeof marked !== 'undefined' && typeof marked.parse === 'function') {
// Define native parser options
const parseOptions = {
breaks: true // Natively converts single \n to <br> without string hacks
};
// 🎯 THE NATIVE HOOK: Intercept link token generation during parsing
if ($parameters.OpenLinksInNewTab) {
const customRenderer = new marked.Renderer();
const originalLink = customRenderer.link.bind(customRenderer);
customRenderer.link = function(token) {
const html = originalLink(token);
// Inject target="_blank" and the critical security rel attributes
if (html.startsWith('
return html.replace('
return html;
parseOptions.renderer = customRenderer;
// 4. Render and set clean HTML safely in a single pass
target.innerHTML = marked.parse(cleanText, parseOptions);
} else {
// Fallback: show plain text if library is missing
target.textContent = cleanText;
console.warn('MarkedJS library is not loaded or ready.');
======================================================================================================================================================================
Why this approach is superior:
Zero DOM Layout Thrashing: It doesn't run regex scans on your DOM after painting. It constructs the correct HTML structure directly during the initial parsing phase.
Hardened Security: Built-in protection against Reverse Tabnabbing using rel="noopener noreferrer".
No Unstructured Hack Files: Avoids the need for custom zip file helpers or complex DOM-traversal scripts.
Hope this helps anyone looking to scale their Markdown implementations in OutSystems!______________________________________________________________________________________________________________Disclaimer note: this message was built by AI, but tested by me (a human xD).