Skip to content

feat(site): add mermaid diagram rendering - #2754

Merged
waynesun09 merged 1 commit into
mainfrom
vitepress-mermaid
Jun 29, 2026
Merged

feat(site): add mermaid diagram rendering#2754
waynesun09 merged 1 commit into
mainfrom
vitepress-mermaid

Conversation

@waynesun09

@waynesun09 waynesun09 commented Jun 29, 2026

Copy link
Copy Markdown
Member

Summary

  • Add mermaid diagram rendering to VitePress docs via a custom Mermaid.vue component
  • Diagrams are lazy-loaded — mermaid is only imported on pages that contain ```mermaid code fences, with zero JS overhead on the ~80 other pages
  • Uses defineAsyncComponent + dynamic import('mermaid') in onMounted() instead of vitepress-plugin-mermaid, which registered the component globally and caused ~1.4 MB of modulepreload chunks on every page
  • Alias mermaid to its pre-bundled ESM build (mermaid.esm.mjs) to avoid CJS/ESM dayjs default-export error under the noExternal: [/./] SSR config
  • Pin mermaid ~11.16.0 since the ESM alias targets an undocumented build artifact
  • securityLevel: 'strict' enables DOMPurify sanitization on all SVG output
  • MutationObserver re-renders diagrams on dark/light theme toggle

Files changed

  • website/.vitepress/theme/components/Mermaid.vue — new lazy-loading component (~40 lines)
  • website/.vitepress/theme/index.ts — async component registration via enhanceApp
  • website/.vitepress/config.ts — markdown-it fence transform for ```mermaid blocks, alias comment
  • website/package.json — add mermaid ~11.16.0, no plugin dependency

Test plan

  • Verify mermaid diagrams render on docs/ADRs/0002-initial-fullsend-design (two flowcharts)
  • Verify dark/light theme toggle re-renders diagrams correctly
  • Verify zero mermaid network requests on non-mermaid pages
  • Verify zero mermaid modulepreload links in production build homepage
  • Verify VitePress build passes without errors
  • CI passes

Assisted-by: Claude

@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Enable Mermaid diagram rendering in VitePress docs site

✨ Enhancement ⚙️ Configuration changes 🕐 10-20 Minutes

Grey Divider

AI Description

• Add Mermaid + VitePress Mermaid plugin dependencies for interactive diagram rendering.
• Wrap VitePress config with withMermaid() and enforce Mermaid securityLevel: 'strict'.
• Alias Mermaid to its ESM build to avoid SSR CJS/ESM default-export issues.
Diagram

graph TD
  A["Docs markdown"] --> B(["VitePress build/SSR"]) --> C(["vitepress-plugin-mermaid"]) --> D(["Mermaid (ESM)"])
  E[".vitepress/config.ts"] --> B --> F["Mermaid config: strict"]
  E --> G["Vite alias: mermaid.esm.mjs"] --> D
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Use markdown-it Mermaid rendering instead of VitePress plugin
  • ➕ Potentially simpler integration if you already customize the markdown-it pipeline
  • ➕ More direct control over fence parsing and rendering hooks
  • ➖ More custom code/maintenance than a dedicated VitePress plugin
  • ➖ May still require ESM/CJS workaround depending on Mermaid import path used
2. Pre-render Mermaid to SVG at build time
  • ➕ No client-side Mermaid execution (smaller runtime, faster page load)
  • ➕ Avoids most SSR/runtime module format issues
  • ➖ More complex build pipeline and caching
  • ➖ Loses interactive features unless you add extra tooling

Recommendation: The chosen approach (vitepress-plugin-mermaid + withMermaid() wrapper) is the most maintainable path for VitePress and keeps authoring ergonomics (```mermaid fences). The explicit alias to mermaid.esm.mjs is a pragmatic fix for SSR module-resolution conflicts under the current `noExternal` SSR setup; pre-rendering would be overkill unless client bundle size or runtime execution becomes a concern.

Files changed (2) +10 / -2

Enhancement (1) +8 / -2
config.tsWrap VitePress config with Mermaid plugin + SSR-safe Mermaid alias +8/-2

Wrap VitePress config with Mermaid plugin + SSR-safe Mermaid alias

• Imports and applies 'withMermaid()' around the VitePress config so mermaid code fences render as diagrams. Adds a Vite resolve alias to Mermaid’s pre-bundled ESM entrypoint to avoid SSR CJS/ESM default-export issues, and sets Mermaid 'securityLevel: 'strict''.

website/.vitepress/config.ts

Other (1) +2 / -0
package.jsonAdd Mermaid and VitePress Mermaid plugin dependencies +2/-0

Add Mermaid and VitePress Mermaid plugin dependencies

• Adds 'mermaid' and 'vitepress-plugin-mermaid' to the docs site dependencies so the VitePress integration can render Mermaid diagrams.

website/package.json

@github-actions

github-actions Bot commented Jun 29, 2026

Copy link
Copy Markdown

Site preview

Preview: https://898fced3-site.fullsend-ai.workers.dev

Commit: d9e60a771a2ebf7e20932f749091adcb87a4ab99

@fullsend-ai-review

fullsend-ai-review Bot commented Jun 29, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 4:47 PM UTC · Completed 4:59 PM UTC
Commit: 8e565f7 · View workflow run →

@codecov

codecov Bot commented Jun 29, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@qodo-code-review

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (2) 📘 Rule violations (0) 📜 Skill insights (0)

Context used
✅ Compliance rules (platform): 51 rules

Grey Divider


Remediation recommended

1. Docs Node engine too low 🐞 Bug ☼ Reliability
Description
website/package.json still declares Node ">=18.0" even though the newly-added mermaid dependency
pulls in marked@16.x, which declares Node ">=20" and can break installs/runs on Node 18.
This is a compatibility contract mismatch introduced by adding mermaid.
Code

website/package.json[R11-17]

  "dependencies": {
+    "mermaid": "^11.16.0",
    "vitepress": "^1.6.3",
+    "vitepress-plugin-mermaid": "^2.0.17",
    "vue": "^3.5.13"
  },
  "engines": {
Relevance

⭐⭐⭐ High

Team proactively updates Node requirements for compatibility/EOL (PR2457); likely to bump docs
engines to match deps.

PR-#2457

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The PR adds mermaid; mermaid depends on marked, and marked explicitly requires Node >=20 per the
lockfile, while the docs site's own engines field still allows Node >=18.

website/package.json[11-19]
website/package-lock.json[2747-2774]
website/package-lock.json[2714-2724]
package.json[1-7]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`website/package.json` advertises `engines.node: ">=18.0"`, but `mermaid` depends on `marked@16.x` which declares `engines.node: ">= 20"`. This makes Node 18 a seemingly-supported environment that may not actually work.

## Issue Context
- Root repo already requires Node >=22.
- CI builds the site on Node 22.

## Fix Focus Areas
- website/package.json[17-19]
- (Optional consistency) package.json[5-7]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools



Informational

2. Hardcoded mermaid dist alias 🐞 Bug ⚙ Maintainability
Description
The Vite resolve.alias maps mermaid to a specific node_modules/mermaid/dist/mermaid.esm.mjs file
path, tightly coupling the build to Mermaid’s internal package layout.
This makes future Mermaid upgrades more likely to break the docs build configuration.
Code

website/.vitepress/config.ts[R304-308]

      alias: {
        'vue/server-renderer': path.resolve(__dirname, '..', 'node_modules', 'vue', 'server-renderer', 'index.mjs'),
        'vue': path.resolve(__dirname, '..', 'node_modules', 'vue'),
+        'mermaid': path.resolve(__dirname, '..', 'node_modules', 'mermaid', 'dist', 'mermaid.esm.mjs'),
      },
Relevance

⭐⭐ Medium

No prior reviews on Vite aliasing node_modules; team sometimes avoids hardcoded paths (PR1780), but
alias may be required.

PR-#1780

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The new alias directly targets a deep file under node_modules rather than resolving the module
specifier, which is inherently layout-dependent.

website/.vitepress/config.ts[302-308]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
The config hardcodes an absolute path into `website/node_modules/.../dist/mermaid.esm.mjs`. This is fragile when package managers change layout or Mermaid changes its dist structure.

## Issue Context
Node 22 is already used in CI and the repo root engines, so using `import.meta.resolve(...)` is viable to resolve the file path without assuming `node_modules` layout.

## Fix Focus Areas
- website/.vitepress/config.ts[302-317]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Qodo Logo

@fullsend-ai-review

Copy link
Copy Markdown

Looks good to me


Labels: PR modifies the VitePress documentation site

@fullsend-ai-review fullsend-ai-review Bot added ready-for-merge All reviewers approved — ready to merge component/docs User-facing documentation labels Jun 29, 2026
@fullsend-ai-review

fullsend-ai-review Bot commented Jun 29, 2026

Copy link
Copy Markdown

🤖 Review · ⚠️ Cancelled · Started 5:55 PM UTC · Ended 6:01 PM UTC
Commit: 657bf48 · View workflow run →

Add mermaid diagram support to VitePress docs via a custom Mermaid.vue
component that dynamically imports mermaid only on pages containing
```mermaid code fences. Uses defineAsyncComponent for zero overhead on
non-diagram pages (~80 of ~81 pages).

Key decisions:
- Alias mermaid to its pre-bundled ESM build (mermaid.esm.mjs) to avoid
  dayjs CJS default-export error under noExternal: [/./] SSR config
- Pin mermaid ~11.16.0 since the ESM alias targets an undocumented build
  artifact that could change in a minor release
- securityLevel: 'strict' enables DOMPurify sanitization on all SVG output
- MutationObserver re-renders diagrams on dark/light theme toggle

Assisted-by: Claude
Signed-off-by: Wayne Sun <gsun@redhat.com>
@fullsend-ai-review

fullsend-ai-review Bot commented Jun 29, 2026

Copy link
Copy Markdown

🤖 Finished Review · ✅ Success · Started 6:05 PM UTC · Completed 6:16 PM UTC
Commit: d9e60a7 · View workflow run →

@waynesun09
waynesun09 added this pull request to the merge queue Jun 29, 2026
Merged via the queue into main with commit 8e86081 Jun 29, 2026
13 checks passed
@waynesun09
waynesun09 deleted the vitepress-mermaid branch June 29, 2026 18:12
@fullsend-ai-retro

fullsend-ai-retro Bot commented Jun 29, 2026

Copy link
Copy Markdown

🤖 Retro · ❌ Terminated · Started 6:16 PM UTC · Ended 6:22 PM UTC
Commit: 657bf48 · View workflow run →

@fullsend-ai-review

Copy link
Copy Markdown

Review skipped — this PR is already merged.

The /fs-review command only reviews open pull requests.

Posted by fullsend post-review check

@fullsend-ai-retro

Copy link
Copy Markdown

🤖 Finished Retro · ❌ Failure · Started 6:16 PM UTC · Completed 6:22 PM UTC
Commit: d9e60a7 · View workflow run →

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

component/docs User-facing documentation ready-for-merge All reviewers approved — ready to merge

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants