SVG graphics
The SVG primitive set, direct presentation props, scoped definitions, SVG text, and the supported numeric boundary.
Nuxt PDF ships a set of SVG drawing primitives that render through the same
layout and render engine as the document primitives. A PdfSvg participates in
normal page flow as a flex leaf, measured from its viewBox aspect ratio.
The primitive set
| Component | Role |
|---|---|
PdfSvg | SVG root; a flex leaf in page flow |
PdfG | A group; presentation attributes cascade to children |
PdfPath | A path from a d string |
PdfRect | A rectangle (x, y, width, height, rx, ry) |
PdfCircle | A circle (cx, cy, r) |
PdfEllipse | An ellipse (cx, cy, rx, ry) |
PdfLine | A line (x1, y1, x2, y2) |
PdfPolyline | An open polyline from a points string |
PdfPolygon | A closed polygon from a points string |
PdfDefs | Holds referenceable defs (gradients, clip paths) |
PdfClipPath | A clip path referenced by clipPath="url(#id)" |
PdfLinearGradient / PdfRadialGradient | Gradients referenced by fill="url(#id)" |
PdfStop | A gradient color stop |
PdfTspan | A text span inside an SVG PdfText |
Full prop tables are in the primitive reference.
A basic drawing
<PdfSvg viewBox="0 0 120 120" :style="{ width: 120, height: 120 }">
<PdfRect x="8" y="8" width="104" height="104" rx="12" fill="#eef2ee" />
<PdfCircle cx="60" cy="60" r="34" fill="#315d3b" />
<PdfPath d="M44 62 l12 12 l22 -26" stroke="#ffffff" stroke-width="6" fill="none" />
</PdfSvg>Presentation is direct, not a style cascade
Set SVG paint and geometry with direct props. PdfG and the shape primitives
do not accept a generic style prop, so there is no prop-versus-style
precedence to remember. transform is also a direct SVG prop; page-flow
primitives such as PdfView put transforms in PdfStyle instead.
PdfSvg is the exception only at the page-flow boundary: its style sizes and
positions the SVG root in the surrounding PDF layout. It does not become a bag
of SVG presentation attributes. SVG PdfText may use style for text metrics
such as fontFamily and fontSize, but its paint color is the direct fill
prop.
Kebab-case attributes written in Vue templates (stroke-width, stop-color)
are coerced to the camelCase keys the renderer reads, so both forms work:
<!-- stroke-width and strokeWidth are equivalent on SVG nodes -->
<PdfLine x1="0" y1="0" x2="100" y2="0" stroke="#333" stroke-width="2" />Presentation attributes set on a PdfG cascade to its children:
<PdfG fill="#315d3b" transform="translate(10 10) rotate(15)">
<PdfRect x="0" y="0" width="20" height="20" />
<PdfRect x="30" y="0" width="20" height="20" />
</PdfG>Numbers and transforms
Geometry accepts finite numbers or numeric strings; percentage strings are
accepted only by props typed as PdfSvgLength. strokeWidth does not accept a
percentage. Widths and radii must be non-negative, opacity and gradient-stop
values must be between 0 and 1 (or 0% and 100%), and a viewBox must
contain four finite numbers with positive width and height.
The transform surface is deliberately small: one to three space-separated
translate(...) or rotate(...) operations with unitless numeric arguments.
Scale, matrix, skew, angle units, and arbitrary transform strings are rejected.
Explicit zeroes keep SVG meaning despite truthiness fallbacks in the pinned serializer:
fillOpacity="0"paints fully transparent;strokeWidth="0"paints no stroke (not a PDF hairline); and- a zero linear-gradient
x2, or zero radial-gradientcx,cy,fx,fy, orr, remains zero.
Nuxt PDF repairs those values after layout on the disposable resolved tree, immediately before serialization. This is an engine-boundary correction, not a second authoring format.
Gradients and clip paths
Define a gradient or clip path inside a PdfDefs and reference it by url(#id):
<PdfSvg viewBox="0 0 200 100" :style="{ width: 200, height: 100 }">
<PdfDefs>
<PdfLinearGradient id="brand" x1="0" y1="0" x2="1" y2="0">
<PdfStop offset="0" stop-color="#315d3b" />
<PdfStop offset="1" stop-color="#7bbf88" />
</PdfLinearGradient>
</PdfDefs>
<PdfRect x="0" y="0" width="200" height="100" fill="url(#brand)" />
</PdfSvg>url(#id) reference resolves only against a PdfDefs in the same PdfSvg
subtree. Definition ids must be safe and unique within that SVG, and each SVG
accepts at most one PdfDefs. A missing, malformed, or incompatible reference
(for example a clip path used as a fill) fails with PDF_TREE_INVALID; it is
never rendered as an accidental fallback. The same definition id may be reused
in another PdfSvg because scopes are independent.SVG text
PdfText has two context-specific contracts. In page flow it accepts wrapping,
pagination, bookmark, destination, and dynamic-text props. Inside PdfSvg, both
x and y are required, fill is the direct paint prop, and page-flow-only
props are rejected. SVG text may hold PdfTspan children, which join and chain
along the x-axis:
<PdfSvg viewBox="0 0 200 40" :style="{ width: 200, height: 40 }">
<PdfText :x="0" :y="24" fill="#18251d">
<PdfTspan>Total </PdfTspan>
<PdfTspan fill="#315d3b">EUR 1,250.00</PdfTspan>
</PdfText>
</PdfSvg>The text content is preserved in the extracted page text, so it remains
selectable and testable. PdfTspan is intentionally narrow: it accepts only
x, y, and fill; it has no generic style, stroke, transform, or other
shape presentation props.
Nesting rules and what is not claimed
PdfSvg is a valid child of PdfPage and PdfView but is rejected directly
inside PdfText. Leaf shapes stay childless. Each container accepts only its
valid children; invalid nesting fails with a targeted diagnostic.
Within SVG, the following are not claimed in the current alpha:
Marker(markerStart/markerMid/markerEnd);- alternate
gradientUnits,gradientTransform, gradient inheritance, andpreserveAspectRatiomodes; - radial-gradient inner radius (
fr), which the pinned renderer hardcodes to zero; and - SVG image files as an image source.