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-core 1.3.3 installed.
  • A Backstage instance on @backstage/plugin-techdocs 1.10.0+ with mkdocs-mermaid2-plugin enabled in the build.
  • A service repo with the backstage.io/techdocs-ref: dir:. annotation already set.
  • The techdocs-core plugin active in mkdocs.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

  1. Enable the Mermaid plugin in mkdocs.yml. Order matters: techdocs-core first, then mermaid2. 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_format
    

    The superfences custom fence is what tells MkDocs to leave ```mermaid blocks untouched so the browser-side Mermaid runtime can render them, rather than treating them as code.

  2. Author the diagram as a fenced mermaid block 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)]
    ```
    
  3. 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
    ```
    
  4. Reference the page in nav so 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.