fix: Revert back to mermaid.js for diagram rendering & update styling#2949
Conversation
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
@claude review |
There was a problem hiding this comment.
LGTM — straightforward library swap in a single component; the two inline comments are render-cycle UX nits and don't block.
Extended reasoning...
Overview
This PR reverts components/Mermaid.tsx from the beautiful-mermaid library back to mermaid (v11.15.0), and refactors the component into a client-side, theme-aware renderer with module-level result/in-flight caches, a SHA-256-keyed deterministic diagram id, a skeleton placeholder, and a code-block fallback on render failure. The CSS change adjusts the rendered SVG to center horizontally rather than stretch to full width. package.json/pnpm-lock.yaml reflect the dependency swap.
Security risks
None of meaningful concern. securityLevel: "loose" is set on mermaid — this is required for HTML labels but it does mean any author-controlled diagram source can inject HTML; however, the diagram source comes from in-repo MDX content, not end-user input, so the trust boundary is the same as any other code in the docs repo. The cache key SHA hash is non-cryptographic in purpose (just an id) so the SHA-256 choice is fine. dangerouslySetInnerHTML is used on mermaid's own rendered SVG, which is the standard pattern. No auth, crypto, or permissions code is touched.
Level of scrutiny
Low-to-moderate. This is a docs-site (langfuse-docs) component change — not production app code, no CODEOWNERS-protected paths, no shared infrastructure. The change is self-contained to one component plus its dependency and a small CSS rule. The previous-state library swap pattern is reversible and Vercel preview deployments will visually verify the result before merge.
Other factors
The bug hunter found two issues, both explicitly classified as nits: (1) a one-frame skeleton flash on warm-cache remount because the cache lookup is in useEffect instead of a lazy useState initializer, and (2) a double initial render because next-themes returns resolvedTheme=undefined on the first pass and the cache key includes themeMode. Both are UX/perf optimizations on a correctly-functioning rewrite — not correctness bugs — so they don't warrant blocking. Inline comments are already attached for the author to consider.
ca4a053 to
4b8b282
Compare
4b8b282 to
c5a8c43
Compare
Greptile Summary
Reverts from the
beautiful-mermaidserver-side renderer back to nativemermaid.jswith client-side async rendering, theme-aware configuration driven by CSS custom properties, and a skeleton loading state while the diagram resolves.components/Mermaid.tsxis a full rewrite: the component is now a"use client"component that lazily importsmermaid, caches rendered SVGs by a key that encodes chart content + resolved theme + current CSS variable values, and renders a pulse-animation skeleton until the SVG is ready.style.cssadjusts.mermaid-diagram svgtowidth: auto; margin-inline: autoso diagrams centre rather than stretch to full container width.package.json/pnpm-lock.yamlswapbeautiful-mermaidformermaid ^11.15.0.Confidence Score: 3/5
The rendering logic is mostly sound but has a race condition that can silently produce wrong diagrams when a user switches themes while a chart is still rendering.
The
chartHashused as the mermaid DOM element ID is derived only from chart content, so two simultaneous renders of the same chart triggered by a theme change share an identical element ID and can interfere with each other inside mermaid's temporary DOM node logic. Additionally,securityLevel: "loose"strips sanitisation from diagram labels — acceptable for a fully-controlled static site but worth an explicit decision.components/Mermaid.tsx — the new rendering pipeline and its caching/ID strategy need attention.
Security Review
components/Mermaid.tsx, line 50):securityLevel: "loose"disables mermaid's built-in HTML sanitisation. Combined withhtmlLabels: true, any HTML placed in a diagram label (including<script>or event handlers) would execute in the reader's browser. The attack surface is limited to users who can commit to the docs repo, but the blast radius is every visitor to any page containing a mermaid diagram.Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart TD A["Mermaid component mounts\n(chart, resolvedTheme)"] --> B{Cache hit?} B -- Yes --> C[setRenderedSvg immediately] B -- No --> D[Show skeleton UI] D --> E["hashString(chart)\nimport('mermaid')"] E --> F["mermaid.initialize(getMermaidConfig)\nCSS vars → themeVariables"] F --> G["mermaid.render('mermaid-diagram-{hash}', chart)"] G --> H{Success?} H -- Yes --> I[Store in renderedSvgCache] I --> J[setRenderedSvg → hide skeleton] H -- No --> K[setError → show raw chart in pre] L["resolvedTheme changes"] --> M["useEffect re-runs\nnew cache key = theme + CSS vars + chart"] M --> BPrompt To Fix All With AI
Reviews (1): Last reviewed commit: "fix: Revert back to mermaid.js for diagr..." | Re-trigger Greptile
Context used:
Learned From
langfuse/langfuse-python#1387