Skip to content

fix: render Mermaid diagrams in PDF export#56

Merged
aniongithub merged 1 commit into
mainfrom
fix-pdf-export-mermaid-diagrams
Jul 3, 2026
Merged

fix: render Mermaid diagrams in PDF export#56
aniongithub merged 1 commit into
mainfrom
fix-pdf-export-mermaid-diagrams

Conversation

@aniongithub

Copy link
Copy Markdown
Owner

Problem

PDF exports were showing Mermaid diagrams as raw code blocks instead of rendered SVG flowcharts. The headless Chromium (Playwright-bundled) in the devcontainer cannot fetch external CDN resources, so the previous approach of loading Mermaid via a CDN <script type="module"> silently failed.

Solution

Serve mermaid.min.js from the same local HTTP server that serves the HTML document to chromedp. The bundle is located at runtime from webui/node_modules/mermaid/dist/mermaid.min.js. When not found, the export degrades gracefully (shows code blocks as plain text).

Changes

internal/share/pdf.go

  • Replace CDN ES module import with local /mermaid.min.js script tag
  • Add findMermaidJS() to locate the Mermaid bundle from common paths (project root, relative to package dir, relative to executable)
  • Add pagesHaveMermaid() to detect mermaid blocks and skip loading when unnecessary
  • Serve mermaid.min.js from the local HTTP server alongside the HTML
  • Add data-mermaid-done signal: set immediately when no mermaid, or after rendering completes

internal/share/pdf_test.go

  • Rewrite TestPDFMermaidRendering to verify actual SVG rendering via chromedp (checks for <svg> elements, flowchart class, and removal of original code block)
  • Add TestPDFRenderHTMLNoMermaid to verify no mermaid script is included for plain pages
  • Update TestPDFRenderHTMLContainsMermaidScript for new local-server approach

How it works

  1. pagesHaveMermaid() scans page bodies for ```mermaid blocks
  2. If found, findMermaidJS() reads the ~3MB UMD bundle from disk
  3. htmlToPDF() starts a local HTTP server with two routes: / (the HTML) and /mermaid.min.js (the bundle)
  4. The HTML includes a <script> that initializes Mermaid, replaces <code class="language-mermaid"> blocks with <div class="mermaid">, calls mermaid.run(), then signals completion
  5. chromedp polls for data-mermaid-done="true" before printing to PDF

Testing

All tests pass including the new mermaid rendering verification:

ok  github.com/aniongithub/mind-map/internal/share  0.677s

The PDF export was failing to render Mermaid diagrams because the
headless Chromium in the devcontainer cannot fetch external CDN
resources. Mermaid code blocks were showing as raw text instead of
rendered SVG flowcharts.

Solution: Serve mermaid.min.js from a local HTTP server alongside the
HTML document. The bundle is located at runtime from
webui/node_modules/mermaid/dist/mermaid.min.js. When not found,
degrades gracefully (shows code blocks as-is).

Changes:
- Replace CDN ES module import with local /mermaid.min.js script tag
- Add findMermaidJS() to locate the bundle from common paths
- Add pagesHaveMermaid() to skip mermaid loading when not needed
- Serve mermaid.min.js from the same local HTTP server as the HTML
- Rewrite tests to verify SVG rendering via chromedp assertions
- Add test for no-mermaid path (data-mermaid-done still set)
@aniongithub aniongithub merged commit 26dabe8 into main Jul 3, 2026
1 check passed
@aniongithub aniongithub deleted the fix-pdf-export-mermaid-diagrams branch July 3, 2026 00:58
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.

1 participant