Native canvas pages
What this demonstrates
@quartz-community/canvas-page is a page-type plugin, not a transformer: it takes a
file that is not Markdown at all — vault/experiments/sandbox-tour.canvas, a
JSON Canvas 1.0 document — and emits an HTML route for
it, complete with the site’s layout.
The canvas in this vault is a real diagram of the sandbox: the isolation boundary, the build pipeline, and file nodes pointing at actual pages of this site.
Open it: Sandbox Tour canvas
Configuration used
- source: "@quartz-community/canvas-page"
enabled: true
options:
enableInteraction: true
initialZoom: 0.55
minZoom: 0.1
maxZoom: 4
order: 50initialZoom: 0.55 is a sandbox deviation from the upstream default of 1: the tour canvas
is ~1240 units wide, so opening at just over half scale shows the whole isolation boundary
without the reader having to zoom out first.
The layout is also specialised for this page type:
layout:
byPageType:
canvas:
exclude:
- table-of-contents
positions:
right: []A canvas has no headings, so a table of contents would render empty; dropping the right sidebar entirely gives the canvas the full content column.
Content used
The canvas source is standard JSON. Three node kinds and labelled edges:
{
"nodes": [
{ "id": "group-boundary", "type": "group", "x": -40, "y": 240,
"width": 1240, "height": 420, "color": "1", "label": "Isolation boundary" },
{ "id": "shared", "type": "text", "x": 0, "y": 290, "width": 360, "height": 240,
"color": "1", "text": "## Shared engine\n\n`/home/loca/dev/quartz/quartz`" },
{ "id": "page-config", "type": "file", "file": "config/index.md",
"x": 320, "y": 1250, "width": 280, "height": 100, "color": "2" },
{ "id": "spec-link", "type": "link", "url": "https://jsoncanvas.org/spec/1.0/",
"x": 960, "y": 1400, "width": 200, "height": 100, "color": "5" }
],
"edges": [
{ "id": "e-shared-sandbox", "fromNode": "shared", "fromSide": "right",
"toNode": "sandbox-engine", "toSide": "left",
"label": "no shared state", "color": "1" }
]
}Note what each node type costs the build: text nodes are rendered as Markdown at build
time, file nodes become internal links (with popover previews, since enablePopovers is
on), and link nodes become external anchors.
What the rendered output proves
The canvas route emits real HTML — a canvas container element with one positioned node
element per JSON node, the text nodes’ Markdown already converted to HTML, an SVG layer for
the edges, and a <title> from the file name. The interaction layer (pan and zoom) is
client-side, but the content is server-rendered: with JavaScript disabled the nodes and
their text are still in the document.
The route also proves the byPageType override applied: the canvas page has no
table-of-contents element and no right sidebar, while this Markdown page has both.
safe_for_shared_engine
true — page-type plugins only claim files with their own extension, so a vault with no
.canvas files emits exactly the same routes as before.