sandboxBaseUrl Configuration Option
This page demonstrates the new sandboxBaseUrl configuration option for Mermaid.js,
which enables relative URL resolution when using securityLevel: 'sandbox'.
When Mermaid renders diagrams with securityLevel: 'sandbox', the SVG is embedded
inside an iframe using a data: URI. This provides strong security isolation but
creates a problem: relative URLs in clickable links don't work.
This happens because data: URIs have no base URL context. When you click a link
like ./page.html inside a data URI iframe, the browser has no way to resolve
what ./ refers to.
The sandboxBaseUrl option tells Mermaid what base URL to use for resolving
relative links. Before embedding the SVG in the sandbox iframe, Mermaid pre-resolves all
relative URLs to absolute URLs using this base.
Add sandboxBaseUrl to your Mermaid configuration:
mermaid.initialize({
startOnLoad: true,
securityLevel: 'sandbox',
sandboxBaseUrl: window.location.href, // or any absolute URL
flowchart: { htmlLabels: false } // recommended for sandbox mode
});
| Option | Type | Description |
|---|---|---|
sandboxBaseUrl |
string | Base URL for resolving relative links. Only applies when securityLevel is 'sandbox'. |
flowchart.htmlLabels |
boolean | Set to false for sandbox mode. When true (default), labels use <foreignObject> with HTML, which doesn't render in data: URI iframes due to security restrictions. Setting to false uses pure SVG text instead. |
strict, loose, antiscript), relative URLs work
normally because the SVG is rendered directly in the page context.
Click "Index Page" to test relative URL resolution (opens ./index.html):
flowchart LR
A[This Page] --> B[Index Page]
A --> C[GitHub]
click B "./index.html" "Relative link - should open index.html"
click C "https://github.com/mermaid-js/mermaid" "Absolute link - opens GitHub"
Without sandboxBaseUrl, clicking "Index Page" would fail silently.
Click to jump to different sections of this page:
flowchart TD
A["#problem"] --> B["#solution"]
B --> C["#configuration"]
C --> D["#url-types"]
D --> E["#demo"]
click A "#problem" "Jump to Problem section"
click B "#solution" "Jump to Solution section"
click C "#configuration" "Jump to Configuration section"
click D "#url-types" "Jump to URL Types section"
click E "#demo" "Jump to Demo section"
This diagram shows different URL types that are handled:
flowchart TD
A["Relative: ./index.html"] --> B["Hash: #url-types"]
B --> C["Absolute: https://mermaid.js.org"]
click A "./index.html" "Relative URL - resolved using sandboxBaseUrl"
click B "#url-types" "Hash URL - jumps to section below"
click C "https://mermaid.js.org" "Absolute URL - unchanged, opens directly"
| URL Pattern | Example | Behavior |
|---|---|---|
| Relative | ./page.html, ../parent.html |
Resolved against sandboxBaseUrl |
| Root-relative | /absolute/path.html |
Resolved against origin of sandboxBaseUrl |
| Hash/Anchor | #section-id |
Resolved against sandboxBaseUrl |
| Absolute | https://example.com |
Unchanged (already absolute) |
| Protocol-relative | //example.com/path |
Unchanged (already absolute) |
| Special protocols | mailto:, tel:, javascript: |
Unchanged |
The feature works by:
href and xlink:href attributes using querySelectorAllURL constructorinnerHTML (with URLs already resolved)
This DOM-based approach avoids parsing and re-serializing the SVG string, and has zero overhead
when sandboxBaseUrl is not configured.
This feature is implemented in the main Mermaid.js repository. The key files are:
packages/mermaid/src/utils/sandboxUrl.ts - URL resolution utilitypackages/mermaid/src/mermaidAPI.ts - Integration before innerHTML extractionpackages/mermaid/src/schemas/config.schema.yaml - Config schema