Writing TechDocs with MkDocs and Mermaid Diagrams
Diagrams that live as code in the same repo as the docs they illustrate stay accurate, review cleanly in pull requests, and adapt to light and dark themes without binary assets. This how-to shows how to author TechDocs in MkDocs with embedded Mermaid diagrams so they render correctly inside the Backstage reader. It is a focused task within the TechDocs Documentation Pipelines workflow and complements the conventions in MkDocs for Internal Docs.
Prerequisites
- MkDocs 1.6.1 with
mkdocs-techdocs-core1.3.3 installed. - A Backstage instance on
@backstage/plugin-techdocs1.10.0+ withmkdocs-mermaid2-pluginenabled in the build. - A service repo with the
backstage.io/techdocs-ref: dir:.annotation already set. - The
techdocs-coreplugin active inmkdocs.yml(it supplies the theme the reader expects).
# Requires Python >= 3.11
pip install mkdocs-techdocs-core==1.3.3 mkdocs-mermaid2-plugin==1.1.1
Exact Configuration
-
Enable the Mermaid plugin in
mkdocs.yml. Order matters:techdocs-corefirst, thenmermaid2. Pin the Mermaid runtime version so renders are reproducible across CI runners.# mkdocs.yml — requires mkdocs-mermaid2-plugin >= 1.1.0 site_name: payments-api plugins: - techdocs-core - mermaid2: version: 10.9.0 markdown_extensions: - pymdownx.superfences: custom_fences: - name: mermaid class: mermaid format: !!python/name:pymdownx.superfences.fence_code_formatThe
superfencescustom fence is what tells MkDocs to leave```mermaidblocks untouched so the browser-side Mermaid runtime can render them, rather than treating them as code. -
Author the diagram as a fenced
mermaidblock directly in your Markdown. Because it is code, it diffs cleanly in review:<!-- docs/architecture.md --> # Payments API architecture ```mermaid flowchart LR client[Client] --> api[Payments API] api --> queue[(Payment Queue)] queue --> worker[Settlement Worker] worker --> ledger[(Ledger DB)] ``` -
Make Mermaid theme-aware so diagrams are legible in both light and dark Backstage themes. Add an init directive at the top of complex diagrams instead of hardcoding colors:
```mermaid %%{init: {'theme': 'neutral'}}%% sequenceDiagram participant U as User participant P as Portal participant C as Catalog U->>P: open entity page P->>C: fetch techdocs_metadata.json C-->>P: HTML + nav P-->>U: rendered docs ``` -
Reference the page in
navso it appears in the TechDocs sidebar, then build and publish through your normal pipeline (see How to Publish TechDocs to S3 with CI).# mkdocs.yml nav: - Home: index.md - Architecture: architecture.md
Validation
# 1. Strict build catches malformed nav and broken links
mkdocs build --strict
# Expected: exit code 0, "Documentation built in ..." with no WARNINGs
# 2. Confirm the Mermaid runtime script is injected into the page
grep -l "mermaid" site/architecture/index.html
# Expected: site/architecture/index.html
# 3. Confirm the diagram source survived as a <pre class="mermaid"> block
grep -c 'class="mermaid"' site/architecture/index.html
# Expected: a count >= 1 (one per diagram on the page)
If all three checks pass, the diagram will render client-side when Backstage loads the page. Mermaid renders in the browser, so a static grep of the HTML is the reliable CI-time signal.
Edge Cases & Troubleshooting
| Symptom | Root Cause | Resolution |
|---|---|---|
| Diagram shows as raw code text in Backstage | superfences custom fence not configured |
Add the pymdownx.superfences block with the mermaid custom fence |
| Diagram renders locally but blank in Backstage | Backstage CSP blocks the inline Mermaid script | Allow the Mermaid asset in the portal csp config or self-host the runtime |
| Inconsistent rendering across CI runs | Unpinned Mermaid version | Pin version: under the mermaid2 plugin |
| Dark-mode text unreadable | Hardcoded light colors in the diagram | Use %%{init: {'theme':'neutral'}}%% instead of fixed hex colors |
pymdownx extension not found |
pymdown-extensions not installed |
It ships with mkdocs-techdocs-core; reinstall the pinned package |
Frequently Asked Questions
Should I use Mermaid or hand-written SVG for TechDocs diagrams?
Use Mermaid for flowcharts, sequence, and ER diagrams where the layout can be generated — it keeps the source readable and review-friendly. Reserve hand-authored SVG for bespoke diagrams where you need pixel-level control. Both avoid the staleness and theme problems of screenshot images.
Will Mermaid diagrams break my strict build?
No. MkDocs treats the fenced block as opaque content, so mkdocs build --strict validates links and nav but does not parse Mermaid syntax. Catch diagram syntax errors by previewing locally with mkdocs serve before pushing.