Project

General

Profile

Actions

Feature #44425

open

Render Mermaid code blocks as diagrams

Added by Mizuki ISHIKAWA 2 days ago. Updated 1 minute ago.

Status:
New
Priority:
Normal
Assignee:
-
Category:
Text formatting
Target version:
Resolution:

Description

This patch adds support for rendering code blocks written in Mermaid syntax as diagrams using Mermaid.js.

For example, with CommonMark:

```mermaid
flowchart LR
    A[Start] --> B[Process]
    B --> C[End]
```

Or with Textile:

<pre><code class="mermaid">
flowchart LR
    A[Start] --> B[Process]
    B --> C[End]
</code></pre>

These are rendered as diagrams instead of code blocks:

This allows flowcharts, sequence diagrams, class diagrams, and other diagrams to be described as text in wikis, issue descriptions, and other formatted text fields.

Mermaid.js is widely used, and supporting it in Redmine would make it possible to preserve information in a more visual form using diagrams.

Implementation

  • Adds mermaid.min.js 11.17.2
  • Detects mermaid code blocks and renders them as diagrams
  • Loads Mermaid.js lazily only when a Mermaid code block is present, since the library is several MB in size
  • Handles invalid Mermaid syntax without affecting the rest of the page
  • Uses securityLevel: 'strict' to prevent scripts and other unsafe content from being executed from Mermaid diagrams
  • Supports both Textile and CommonMark
  • Adds license information for Mermaid.js and its bundled dependencies
  • Adds tests for the above behavior

Patch

The patch could not be attached directly to this issue because it exceeds the attachment size limit, so it is available from the following GitHub pull request instead: https://patch-diff.githubusercontent.com/raw/ishikawa999/redmine/pull/19.patch
(Source: https://github.com/ishikawa999/redmine/pull/19 )

To download and apply the patch:

curl -o mermaid.patch https://patch-diff.githubusercontent.com/raw/ishikawa999/redmine/pull/19.patch
git am mermaid.patch


Files

mermaid-example.png (51.6 KB) mermaid-example.png Mizuki ISHIKAWA, 2026-09-07 06:33
Actions #1

Updated by Go MAEDA 1 day ago

Mermaid has become widely adopted for creating diagrams in Markdown-based tools, and is supported by major platforms such as GitHub, GitLab, Azure DevOps, and Obsidian. I think Mermaid support would be a valuable addition to Redmine.

As a side benefit, having Mermaid.js available in Redmine could also support future UI improvements beyond Mermaid markup in formatted text. For example, it could be used for workflow visualization (#559) or issue dependency graphs (#2448).

Actions #2

Updated by Marius BĂLTEANU 1 day ago

  • Target version set to 7.1.0
Actions #3

Updated by Florian Walchshofer about 9 hours ago

Thanks for the patch. Overall, I like the implementation. The amount of core changes is relatively small, Mermaid is loaded only when needed, and features such as lazy loading and one-time initialization are implemented cleanly.

I also agree with Go MAEDA that having Mermaid support available directly in Redmine could enable additional use cases beyond wiki content.

One concern is that Mermaid is a rather actively developed project with frequent releases. Bundling it in Redmine core means tracking Mermaid updates, security fixes and related third-party dependencies over time. An alternative approach could be an optional Mermaid CLI/CGI integration with server-side SVG/PNG generation, allowing each Redmine installation to decide whether to enable it and keeping Mermaid outside the core dependency chain.

However, this would also make the integration and deployment more complex. Therefore, I still support the proposed JavaScript integration, as it is simple, widely adopted and probably the most practical solution for most Redmine installations.

Regarding the current patch itself, I only have one question:

mermaid.run({ nodes: [container], suppressErrors: true })

From my testing, with suppressErrors: false Mermaid parser and validation errors are propagated to the Promise rejection handler, for example invalid diagram types or syntax errors. This causes the .catch() block to run, while the original code block remains visible.

With suppressErrors: true, these errors no longer seem to reach the .catch() block, so no error is logged and the Mermaid-generated error rendering is shown instead.

Would it make sense to use suppressErrors: false here, hide the Mermaid error output, and log or display the actual parser error object?
The error details often include the exact line and syntax problem, which can be very helpful for users debugging Mermaid diagrams.

Actions #4

Updated by Mizuki ISHIKAWA about 1 hour ago

Florian Walchshofer wrote in #note-3:

One concern is that Mermaid is a rather actively developed project with frequent releases. Bundling it in Redmine core means tracking Mermaid updates, security fixes and related third-party dependencies over time. An alternative approach could be an optional Mermaid CLI/CGI integration with server-side SVG/PNG generation, allowing each Redmine installation to decide whether to enable it and keeping Mermaid outside the core dependency chain.

Thank you for the feedback.

I have not tested this approach yet, but I think it should be possible to enable Mermaid conversion only when Mermaid CLI is available, similar to other features that depend on external commands such as Ghostscript or ImageMagick.
Personally, I prefer the Mermaid.js approach because the implementation is simpler. However, if the Mermaid CLI approach is considered preferable given the maintenance burden of keeping Mermaid.js and its dependencies up to date, I would respect that decision.

With suppressErrors: true, these errors no longer seem to reach the .catch() block, so no error is logged and the Mermaid-generated error rendering is shown instead.

You're right. I've updated the pull request. https://github.com/ishikawa999/redmine/pull/19/changes/71ca601f747d8cccb67816ddb9ec87f1ebebb5fb

Actions #5

Updated by Marius BĂLTEANU 1 minute ago

Florian Walchshofer wrote in #note-3:

[..]
One concern is that Mermaid is a rather actively developed project with frequent releases. Bundling it in Redmine core means tracking Mermaid updates, security fixes and related third-party dependencies over time. An alternative approach could be an optional Mermaid CLI/CGI integration with server-side SVG/PNG generation, allowing each Redmine installation to decide whether to enable it and keeping Mermaid outside the core dependency chain.

That also means the integration can break after a server-side Mermaid CLI/CGI update. Additionally, server-side rendering requires Puppeteer, which makes installation and maintenance much more complex.

Overall, I am in favor of bundling the JS library inside Redmine. We can cut new releases for important upstream security fixes, just as we already do for other dependencies.

Actions

Also available in: Atom PDF