Guide

Entry points

Fenced vega blocks and ::vega component directives — both produce the same Vega AST node.

Both entry points produce identical ['Vega', VegaNodeAttrs] AST nodes. Map them with the shipped Vue component (components="{ Vega }") or a custom renderer.

1 — Fenced ````vega` block (literal / static)

Code-fence content is opaque to Comark's parser — {…} is never treated as directive attribute syntax, so raw JSON is always safe here. The block is replaced in the AST with a ['Vega', { spec, engine }] component node.

```vega-lite
{
  "$schema": "https://vega.github.io/schema/vega-lite/v6.json",
  "mark": "bar",
  "data": { "values": [{ "x": "A", "y": 4 }, { "x": "B", "y": 6 }] },
  "encoding": {
    "x": { "field": "x", "type": "nominal" },
    "y": { "field": "y", "type": "quantitative" }
  }
}
```

Use vega` for a full Vega spec; use vega-litefor a Vega-Lite spec. When$schema` is present, the engine is auto-detected from the URL regardless of the language tag.

2 — ::vega component directive (dynamic / bound)

:prop="expression" attrs are preserved verbatim for @comark/binding to resolve against frontmatter or runtime data at render time. Plain prop="value" attrs remain literal strings.

::vega{:spec="report.chart" engine="vega-lite"}

Multiple bindings are all preserved:

::vega{:spec="dashboard.revenue" :width="panel.w" engine="vega-lite"}

A code-fenced body can supply a literal spec when no :spec binding is present:

::vega{engine="vega-lite"}
```
{ "mark": "bar", … }
```
::

Spec sources for <Vega> entry points

SourceSyntaxNotes
Fenced code blockvega-lite … Literal static spec. Engine auto-detected from $schema or language tag.
:spec= binding attr::vega{:spec="expr"}Resolved at render time by @comark/binding.
Code-fenced directive body::vega + fenced bodyLiteral spec in directive body (no :spec binding present).
For static output without a runtime component, use inline-SVG directives (::vl, ::vg, ::chart) instead.
Copyright © 2026