MkDocs
A plot fence in your MkDocs pages becomes a chart: a SuperFences custom fence keeps the block as plain text with its name, and plotdown.js draws it. It works with Material for MkDocs, its dark palette and its instant navigation.
mkdocs.yml
markdown_extensions:
- pymdownx.highlight
- pymdownx.superfences:
custom_fences:
- name: plot
class: plot
format: !!python/name:pymdownx.superfences.fence_code_format
- name: oplot
class: oplot
format: !!python/name:pymdownx.superfences.fence_code_format
- name: observable-plot
class: observable-plot
format: !!python/name:pymdownx.superfences.fence_code_format
extra_javascript:
- path: https://cdn.jsdelivr.net/npm/@devlooped/plotdown/dist/plotdown.js
type: module
Each fence becomes <pre class="plot"><code>…</code></pre>, which plotdown.js finds. type: module needs MkDocs 1.5 or later; with an older MkDocs, list the classic build https://cdn.jsdelivr.net/npm/@devlooped/plotdown/dist/plotdown.iife.js as a plain string instead.
Write a chart
```plot
{
"y": {"grid": true},
"marks": [
{"mark": "barY", "data": [{"species": "Adelie", "mass": 3750}, {"species": "Gentoo", "mass": 5000}], "x": "species", "y": "mass", "fill": "species"},
{"mark": "ruleY", "data": [0]}
]
}
```
The spec lists the marks and options; the playground checks a block as you type.
Check it
mkdocs serve, then open the page: each block shows as a chart with a Source button. A block with a mistake stays code, with the reason under it (plotdown: unknown mark "pie" at $.marks[0].mark).
Notes
- The custom fences are needed. Without them, Pygments has no lexer for
plotand writes<div class="highlight"><pre><span></span><code>, or<div class="language-text highlight">withpygments_lang_class: true: the fence name is gone, and no script can tell the block from any other code. - Material's palette: under
scheme: slatethe charts are drawn dark, on the page's background. - Instant navigation (
navigation.instant) is fine:plotdown.jswatches the page and draws the blocks of each page Material swaps in. - Remote data (a
"url"indata) is off. MkDocs cannot put attributes on the script tag, so set it in a script listed first:extra_javascript: [plotdown-config.js, …]withglobalThis.plotdownConfig = {allowRemote: ["https://data.example"]};. - Python-Markdown without SuperFences (
fenced_code) writes<pre><code class="language-plot">, which works as is.
Note
Tried with MkDocs 1.6.1, Material for MkDocs 9.8.1 and PyMdown Extensions 13.1 on 2026-11-12.