Skip to content

feat: add support for inline markdown links in text rendering#7470

Open
taoqf wants to merge 9 commits intomermaid-js:developfrom
taoqf:develop
Open

feat: add support for inline markdown links in text rendering#7470
taoqf wants to merge 9 commits intomermaid-js:developfrom
taoqf:develop

Conversation

@taoqf
Copy link

@taoqf taoqf commented Mar 10, 2026

📑 Summary

Brief description about the content of your PR.

Resolves #

📏 Design Decisions

Describe the way your implementation works or what design decisions you made if applicable.

📋 Tasks

Make sure you

  • 📖 have read the contribution guidelines
  • 💻 have added necessary unit/e2e tests.
  • 📓 have added documentation. Make sure MERMAID_RELEASE_VERSION is used for all new features.
  • 🦋 If your PR makes a change that should be noted in one or more packages' changelogs, generate a changeset by running pnpm changeset and following the prompts. Changesets that add features should be minor and those that fix bugs should be patch. Please prefix changeset messages with feat:, fix:, or chore:.

@netlify
Copy link

netlify bot commented Mar 10, 2026

Deploy Preview for mermaid-js ready!

Name Link
🔨 Latest commit 3b12821
🔍 Latest deploy log https://app.netlify.com/projects/mermaid-js/deploys/69b220d29038d8000879c073
😎 Deploy Preview https://deploy-preview-7470--mermaid-js.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@changeset-bot
Copy link

changeset-bot bot commented Mar 10, 2026

🦋 Changeset detected

Latest commit: 3b12821

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
mermaid Minor

Not sure what this means? Click here to learn what changesets are.

Click here if you're a maintainer who wants to add another changeset to this PR

@taoqf
Copy link
Author

taoqf commented Mar 10, 2026

#1279

@pkg-pr-new
Copy link

pkg-pr-new bot commented Mar 10, 2026

Open in StackBlitz

@mermaid-js/examples

npm i https://pkg.pr.new/@mermaid-js/examples@7470

mermaid

npm i https://pkg.pr.new/mermaid@7470

@mermaid-js/layout-elk

npm i https://pkg.pr.new/@mermaid-js/layout-elk@7470

@mermaid-js/layout-tidy-tree

npm i https://pkg.pr.new/@mermaid-js/layout-tidy-tree@7470

@mermaid-js/mermaid-zenuml

npm i https://pkg.pr.new/@mermaid-js/mermaid-zenuml@7470

@mermaid-js/parser

npm i https://pkg.pr.new/@mermaid-js/parser@7470

@mermaid-js/tiny

npm i https://pkg.pr.new/@mermaid-js/tiny@7470

commit: 844fed2

@codecov
Copy link

codecov bot commented Mar 10, 2026

Codecov Report

❌ Patch coverage is 1.17647% with 84 lines in your changes missing coverage. Please review.
✅ Project coverage is 3.52%. Comparing base (bc60cc0) to head (3b12821).

Files with missing lines Patch % Lines
packages/mermaid/src/diagrams/sequence/svgDraw.js 0.00% 44 Missing ⚠️
packages/mermaid/src/rendering-util/createText.ts 0.00% 18 Missing ⚠️
...mermaid/src/rendering-util/handle-markdown-text.ts 0.00% 14 Missing ⚠️
packages/mermaid/src/rendering-util/splitText.ts 0.00% 8 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@            Coverage Diff             @@
##           develop   #7470      +/-   ##
==========================================
- Coverage     3.53%   3.52%   -0.01%     
==========================================
  Files          495     496       +1     
  Lines        49139   49218      +79     
  Branches       772     772              
==========================================
  Hits          1736    1736              
- Misses       47403   47482      +79     
Flag Coverage Δ
unit 3.52% <1.17%> (-0.01%) ⬇️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
packages/mermaid/src/rendering-util/types.ts 100.00% <100.00%> (ø)
packages/mermaid/src/rendering-util/splitText.ts 1.08% <0.00%> (-0.02%) ⬇️
...mermaid/src/rendering-util/handle-markdown-text.ts 0.91% <0.00%> (-0.14%) ⬇️
packages/mermaid/src/rendering-util/createText.ts 0.00% <0.00%> (ø)
packages/mermaid/src/diagrams/sequence/svgDraw.js 0.00% <0.00%> (ø)

... and 1 file with indirect coverage changes

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@argos-ci
Copy link

argos-ci bot commented Mar 10, 2026

The latest updates on your projects. Learn more about Argos notifications ↗︎

Build Status Details Updated (UTC)
default (Inspect) ✅ No changes detected - Mar 12, 2026, 2:21 AM

Copy link
Collaborator

@knsv-bot knsv-bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[sisyphus-bot]

Thanks for this contribution, @taoqf! Adding inline markdown link support is a useful feature. I have some concerns about security, theming, and test coverage that I'd like to work through before this can land — especially since this touches shared rendering-util/ code that affects all diagram types.

File Triage

Tier Count Files
Tier 1 (full read) 5 createText.ts, handle-markdown-text.ts, handle-markdown-text.spec.ts, splitText.ts, types.ts
Tier 2 (diff + context) 2 svgDraw.js, sequenceDiagram.spec.js
Tier 3 (diff only) 2 changeset, src/docs/syntax/sequenceDiagram.md
Skip (generated) 2 docs/config/setup/mermaid/interfaces/LayoutData.md, docs/syntax/sequenceDiagram.md

What's working well

🎉 [praise] Good use of @braintree/sanitize-url for URL sanitization, and the tests explicitly verify that javascript: and data: URLs are replaced with about:blank. This is the right library for the job.

🎉 [praise] Thorough unit tests in handle-markdown-text.spec.ts — the markdownToLines and markdownToHTML test cases cover single links, multiple links, mixed formatting, and malicious URLs. Nice coverage.

🎉 [praise] The splitText.ts changes correctly propagate the href field through the word-splitting recursion, preserving link context when text wraps.

Things to address

Blocking

🔴 [blocking] No E2E visual regression tests. This PR changes shared rendering code in rendering-util/ (createText.ts, handle-markdown-text.ts, splitText.ts, types.ts) which affects all diagram types that use markdown text — not just sequence diagrams. Additionally, the sequence diagram renderer (svgDraw.js) now renders clickable <a> elements, which is a visual change. Per project conventions, renderer and shared rendering-util changes require E2E tests using imgSnapshotTest() in cypress/integration/rendering/. At minimum, add a sequence diagram E2E test showing links rendering correctly.

Security

🟡 [important] Unescaped href in markdownToHTML string interpolation. In handle-markdown-text.ts, the new link handling builds HTML via template literal:

return `<a href="${href}" target="_blank">${text}</a>`;

While sanitizeUrl() blocks dangerous URL schemes (javascript:, data:, etc. — including mixed-case, entity-encoded, and whitespace-padded variants), it does not HTML-encode special characters. A URL containing " could theoretically break out of the href attribute and inject additional attributes. DOMPurify sanitizes the final output (which mitigates this), but building malformed HTML before sanitization is a fragile pattern — it relies on DOMPurify parsing the broken HTML exactly the same way a browser would (mXSS risk).

Suggested fix: HTML-encode the href before interpolation:

const safeHref = href.replace(/&/g, '&amp;').replace(/"/g, '&quot;');
return `<a href="${safeHref}" target="_blank">${text}</a>`;

Note: The D3 paths in createText.ts and svgDraw.js are safe — D3's .attr() properly encodes attribute values.

Important

🟡 [important] Hardcoded link color #0d47a1. This hex value appears in two places:

  • createText.ts (the diff's updateTextContentAndStyles function): .attr('fill', '#0d47a1')
  • svgDraw.js (the drawText function): .attr('fill', '#0d47a1')

This hardcoded color will look wrong on dark themes and won't respond to theme customization. It should use a theme variable instead. Look at how other diagrams reference themeVariables.textColor or similar — the link color could map to an existing variable or a new one. At minimum, the color should be consistent with the theme's color palette.

🟡 [important] Broad scope with narrow testing. The changes to handle-markdown-text.ts, createText.ts, splitText.ts, and types.ts affect ALL diagram types that render markdown labels (flowchart, class, state, mindmap, etc.), but the tests only exercise sequence diagrams. A link in a flowchart node label (node["\Check docs`"]) would also go through the modified markdownToLines/createText` pipeline. Even if you don't add tests for every diagram, it would be great to acknowledge this scope in the PR description and verify manually that a few other diagram types don't regress.

🟡 [important] Duplicate link rendering logic. Links are rendered in two independent places:

  1. handle-markdown-text.ts + createText.ts — the shared markdown pipeline (used by all diagram types with markdown labels)
  2. svgDraw.js — sequence-diagram-specific regex-based rendering

This duplication means link rendering behavior could diverge (different regex patterns, different sanitization, different styling). Is the svgDraw.js path needed, or does the shared pipeline already handle sequence diagram messages? If sequence diagrams use a separate text rendering path that bypasses createText.ts, this is understandable — but it should be documented in the PR description.

Nit

🟢 [nit] The changeset says minor bump, which is correct for a new feature.

Summary

Severity Count
🔴 blocking 1
🟡 important 4
🟢 nit 1
💡 suggestion 0
🎉 praise 3

The core feature is well-implemented — the markdown parsing, URL sanitization, and word splitting are solid. The main concerns are: (1) the missing E2E tests for a shared rendering change, (2) the hardcoded link color bypassing the theme system, (3) the HTML interpolation pattern in markdownToHTML, and (4) explaining the dual rendering paths. Looking forward to seeing this updated!

@knsv knsv requested a review from aloisklink March 11, 2026 18:31
@taoqf taoqf marked this pull request as draft March 12, 2026 00:58
@taoqf taoqf marked this pull request as ready for review March 12, 2026 02:37
@taoqf
Copy link
Author

taoqf commented Mar 12, 2026

@knsv-bot This PR won't change flowchart's behavior , Just sequenceDiagram

A link in a flowchart node label (node["\Check docs`"]) would also

@taoqf taoqf requested a review from knsv-bot March 13, 2026 07:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants