Authoring TechDocs Diagrams as Code

Diagrams that live as code in the same repository as the docs they illustrate stay accurate, review cleanly in pull requests, and adapt to light and dark themes without shipping binary assets. This how-to shows how to author diagrams directly in MkDocs-based TechDocs using hand-authored inline SVG — the approach this portal standardizes on — so illustrations render identically in the Backstage reader and in every theme. It is a focused task within the TechDocs Documentation Pipelines workflow and complements the Markdown conventions in MkDocs for Internal Docs.

Generator-based tools like Mermaid are a popular alternative: you write a flowchart in a small text grammar and a browser runtime lays it out. That convenience comes with two costs that matter for an internal portal — it pulls a JavaScript runtime into every page, and its generated text often fails contrast in a dark theme because colors are baked at render time. Authoring the SVG yourself removes the runtime, gives pixel control, and lets a single currentColor value flip cleanly between themes. The rest of this page is the copy-and-adapt recipe.

Prerequisites

  • MkDocs 1.6.1 with mkdocs-techdocs-core 1.3.3 installed, so the reader theme matches the rest of your catalog.
  • The md_in_html and attr_list Markdown extensions enabled, which let raw inline markup survive the Markdown render untouched.
  • A service repo with the backstage.io/techdocs-ref: dir:. annotation already set and a working pipeline (see How to Publish TechDocs to S3 with CI).
  • Authors comfortable reading a viewBox coordinate system; no build-time diagram tooling is required.
Toolchain that lets inline SVG survive the Markdown render MkDocs with techdocs-core and the md_in_html extension passes raw SVG straight through to the published HTML. Markdown + inline SVG docs/*.md md_in_html raw markup passthrough mkdocs build --strict site/ HTML graphic intact
The md_in_html extension is the one piece that keeps your hand-authored markup from being escaped into visible source.
# Requires Python >= 3.11
pip install mkdocs-techdocs-core==1.3.3

Exact Configuration

  1. Enable raw-HTML passthrough in mkdocs.yml. Without md_in_html, MkDocs escapes your markup and the reader sees angle-bracket source instead of a picture. Keep techdocs-core first so the theme still resolves.

    # mkdocs.yml — requires mkdocs-techdocs-core >= 1.3.0
    site_name: payments-api
    plugins:
      - techdocs-core
    markdown_extensions:
      - md_in_html
      - attr_list
    nav:
      - Home: index.md
      - Architecture: architecture.md
    
  2. Author the diagram as an inline figure in your Markdown page. Wrap the markup in a figure element and give the graphic a fixed coordinate space with viewBox, an accessible role="img" with a title and description, and shapes painted in currentColor so they inherit the reader’s text color and flip with the theme. The illustration below is itself authored exactly this way — view source on this page to see the pattern.

Anatomy of a theme-safe inline SVG figure A figure wraps an SVG whose viewBox sets coordinates, whose title and description give accessibility, and whose shapes use currentColor. figure.diagram viewBox responsive coordinates title + desc role="img" a11y currentColor theme-flipping fill gradient strokes stay saturated in both themes
Four attributes carry the whole technique: a viewBox, a title/description pair, currentColor fills, and a fixed gradient for strokes.
  1. Reference the page in nav so it appears in the TechDocs sidebar, then build and publish through your normal pipeline. Nothing about publishing changes — the diagram is plain HTML inside the page, so the same generate-and-publish steps ship it.

  2. Keep labels short and inside the canvas. Because you control the coordinates, leave roughly fifteen units of clearance from every edge and size text between eleven and eighteen units so it stays legible when the figure scales down on mobile.

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 graphic survived as real markup, not escaped source
grep -c 'role="img"' site/architecture/index.html
# Expected: a count >= 1 (one per diagram on the page)

# 3. Confirm shapes use the theme-flipping fill rather than baked colors
grep -c 'currentColor' site/architecture/index.html
# Expected: a count >= 1

If all three checks pass, the diagram renders server-side into the published HTML and needs no client runtime. A static grep of the built HTML is therefore a fully reliable CI-time signal — there is nothing to execute in a browser.

Three validation checks before publish A strict build, a grep for role img, and a grep for currentColor confirm the diagram shipped correctly and is theme-safe. Strict build links + nav grep role="img" markup survived grep currentColor theme-safe Publish
All three checks are static string matches, so the pipeline never needs a headless browser to prove a diagram works.

Edge Cases & Troubleshooting

The failures you will hit almost always trace back to one of two mistakes: the markup got escaped because passthrough was off, or a color was hardcoded so it disappears in one theme. The table lists the concrete symptoms and fixes, and the diagram routes each symptom to its cause.

Routing diagram symptoms to their cause Escaped source points to a missing passthrough extension; a blank dark-mode diagram points to hardcoded colors. Source shows as text Blank in dark mode md_in_html missing hardcoded hex fill One-line fix
Two root causes explain nearly every broken diagram; each has a one-line fix in config or in the markup.
Symptom Root Cause Resolution
Diagram shows as raw angle-bracket text in Backstage md_in_html extension not enabled Add md_in_html under markdown_extensions in mkdocs.yml
Graphic renders locally but is blank in the dark theme Shapes use a hardcoded light hex fill Repaint fills and text with currentColor so they follow the theme
Strokes vanish against the panel Stroke color equals the background Use the fixed brand gradient for strokes, which stays saturated in both themes
Labels clipped on mobile Text placed too close to the viewBox edge Keep ~15 units of clearance and font sizes between 11 and 18
Diagram distorted or squashed A fixed width/height set on the element Remove width/height; let the viewBox and CSS scale it responsively

Frequently Asked Questions

When should I still reach for a generator like Mermaid instead of hand-authored SVG?

Reach for a generator when the diagram is large, frequently restructured, and layout-generated — a dependency graph with dozens of nodes, for instance, where hand-placing coordinates is impractical. For the small, stable architecture and sequence diagrams that make up most service docs, inline SVG is faster to keep correct and avoids shipping a runtime and its theme-contrast risks.

Does authoring SVG by hand hurt review speed?

Not in practice. A diagram is a few dozen lines of markup that diffs cleanly, so a reviewer sees exactly which box or arrow changed. That is the same review benefit a text-grammar generator offers, without the extra build dependency.