Skip to content

docs: load mermaid from jsdelivr so the CSP allows it#339

Open
smecsia wants to merge 1 commit into
mainfrom
fix/docs-mermaid-csp-jsdelivr
Open

docs: load mermaid from jsdelivr so the CSP allows it#339
smecsia wants to merge 1 commit into
mainfrom
fix/docs-mermaid-csp-jsdelivr

Conversation

@smecsia

@smecsia smecsia commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

Problem

After #338 (restoring startOnLoad), mermaid diagrams still didn't render on the live docs (e.g. concepts/main-concepts) — the page showed the raw graph TB ... source as text.

Root cause

The docs site enforces a Content-Security-Policy whose script-src allows 'self', googletagmanager, and cdn.jsdelivr.net — but not unpkg.com. The mermaid2 plugin defaults to loading Mermaid from unpkg.com, so the browser blocked the import:

Loading the script 'https://unpkg.com/mermaid@10.6.1/dist/mermaid.esm.min.mjs'
violates the following Content Security Policy directive: "script-src 'self' ... https://cdn.jsdelivr.net". The action has been blocked.

(My earlier local test missed this because http.server sends no CSP.)

Fix

Set the plugin's javascript: option to the jsdelivr URL, which the CSP already allows. The .esm bundle lazy-loads its chunks via relative imports, so those resolve on jsdelivr too (also allowed) — whereas from unpkg they'd have been blocked as well.

Verification

Built the site and served it with the production CSP header, then rendered headless: no CSP violations in the console, and the <div class="mermaid"> now contains a rendered <svg> (confirmed against concepts/main-concepts).

🤖 Generated with Claude Code

Follow-up to the startOnLoad fix (#338): diagrams still didn't render live.
The docs site's Content-Security-Policy permits script-src from
cdn.jsdelivr.net but NOT unpkg.com, and the mermaid2 plugin defaults to
unpkg — so the library load was CSP-blocked and the page showed raw
`graph TB ...` text. Point the plugin's `javascript:` at jsdelivr. The .esm
bundle lazy-loads its chunks via relative URLs, so they resolve on jsdelivr
too (also CSP-allowed).

Verified by serving the built site with the production CSP header and
rendering headless: the mermaid div now draws an <svg>.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Signed-off-by: Ilya Sadykov <177390656+universe-ops@users.noreply.github.com>
@github-actions

Copy link
Copy Markdown

📊 Statement coverage

Measured on the documented included set (see docs/TESTING.md → Coverage scope). Observe-only — no regression gate is enforced yet.

Scope This PR main baseline Δ
Included set (Gold-tier denominator) 90.3% 90.3% +0.0 pp
Full set (whole repo, transparency) 27.6% 27.6% +0.0 pp

Baseline: main @ 9fd95bf

@github-actions

Copy link
Copy Markdown

Semgrep Scan Results

Repository: api | Commit: 99fab75

Check Status Details
⚠️ Semgrep Warning 1 warning(s), 1 total

Scanned at 2026-06-22 14:46 UTC

@github-actions

Copy link
Copy Markdown

Security Scan Results

Repository: api | Commit: 99fab75

Check Status Details
✅ Secret Scan Pass No secrets detected
✅ Dependencies (Trivy) Pass 0 total (no critical/high)
✅ Dependencies (Grype) Pass 0 total (no critical/high)
📦 SBOM Generated 522 components (CycloneDX)

Scanned at 2026-06-22 14:47 UTC

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