Skip to main content

Watermarks

Watermarks are page chrome. They render across every page (front-layer overlay on PDF, header-anchored on DOCX) without affecting flow content. The same JSON renders identically in both formats.

Live example

A real-world Mutual NDA with a DRAFT watermark layered behind page content. Open Template to see the JSON.

Schema

Watermarks live at the root of the document definition as an array — they apply to the document as a whole, not to a particular position in the content flow.

{
"document": {
"watermarks": [
{
"content": { "p": "DRAFT" },
"angle": -30,
"repeat": false,
"style": "draft"
}
],
"content": [ ... ]
}
}
PropertyTypeDefaultDescription
contentContentAny content shape — { "p": "..." } paragraph, { "canvas": { … } } block, or inline tags ([image, …], [barcode, …]). Same content vocabulary as body content.
anglenumber0Rotation in degrees. Negative = counter-clockwise. The content rotates around its own visual center.
repeatbooleanfalsetrue = tile across the page using spacing as the step. false = single instance; placement comes from spacing if provided, otherwise centered on the page.
spacing[x, y]In points. Meaning depends on repeat: tile step when repeat: true, explicit page-coordinate placement of the visual center when repeat: false. Omit or use [0, 0] for centered placement.
stylestringNamed style applied to the watermark content (font size, opacity, color).

Text watermark

The most common shape — bold rotated text with low opacity behind the document body.

{
"document": {
"styles": {
"draft": { "fontSize": 96, "bold": true, "fontColor": "#CCCCCC", "opacity": 0.30 }
},
"watermarks": [
{
"content": { "p": "DRAFT" },
"angle": -30,
"repeat": false,
"style": "draft"
}
],
"content": [
{ "p": "Body content sits beneath the centered DRAFT mark." }
]
}
}

Image watermark

The watermark content is just a paragraph — drop in an [image, …] inline tag and it renders as an image watermark. Style provides the opacity for "faintness".

{
"document": {
"styles": {
"logoFaint": { "opacity": 0.15 }
},
"watermarks": [
{
"content": { "p": "[image, images/logos/acme.png, 240|72]" },
"angle": -30,
"repeat": false,
"style": "logoFaint"
}
],
"content": [ ... ]
}
}

Repeating tile pattern

For internal-doc branding, tile a small mark across the page.

{
"watermarks": [
{
"content": { "p": "[image, images/logos/acme.png, 120|60]" },
"spacing": [250, 200],
"angle": 0,
"repeat": true,
"style": "logoFaint"
}
]
}
Layoutrepeatspacing
Single, centeredfalseomitted or [0, 0]
Single, positionedfalse[centerX, centerY] in page points
Tiled across pagetrue[xStep, yStep] in page points

Positioned watermark — edge-mounted elements

For control numbers, vertical sidebars, edge-mounted barcodes, and other elements anchored to a specific page region, set repeat: false and provide explicit page coordinates in spacing. The values are the visual center of the watermark content in page points (origin at bottom-left).

A vertical sidebar running down the left edge of a portrait LETTER page (612×792):

{
"watermarks": [
{
"content": {
"canvas": {
"size": [22, 620],
"commands": [
{ "type": "line", "points": [{ "x": 6, "y": 14 }, { "x": 6, "y": 606 }], "style": "edgeRule" },
{ "type": "textPath",
"d": "M 14 606 L 14 14",
"text": "[caps]control no. dpa-doc-2026-0457 · scan to verify[/caps]",
"alignment": "middle",
"style": "edgeText" }
]
}
},
"repeat": false,
"spacing": [25, 396]
}
]
}

The canvas (22pt wide × 620pt tall) is anchored with its visual center at [25, 396] — 25pt from the page's left edge, page-center vertically. A mirror watermark with spacing: [587, 396] does the same on the right edge (612 − 25 = 587).

This works for any content shape — a barcode [barcode, code128, …] paragraph rotated with angle: 90 becomes a vertical edge barcode; a small text block at [306, 80] becomes a bottom-edge control number.

achievement-certificate and void-check both ship live examples of this pattern.

Multiple watermarks

The array is composed in order. Layer a faint logo behind a bold DRAFT text overlay:

{
"watermarks": [
{
"content": { "p": "[image, images/logos/acme.png, 200|80]" },
"spacing": [300, 250],
"repeat": true,
"style": "logoFaint"
},
{
"content": { "p": "DRAFT" },
"angle": -35,
"repeat": false,
"style": "draftBold"
}
]
}

Dynamic watermark content

Anywhere $data.* references appear (text, image src, even $data.<key> substitutions inside inline tags), they resolve at render time the same way they do in body content:

{
"watermarks": [
{
"content": { "p": "[image, $data.tenant.logoPath, 120|60]" },
"repeat": true,
"style": "logoFaint"
},
{
"content": { "p": "$data.classification" },
"repeat": false,
"style": "classification"
}
]
}

Style properties that matter for watermarks

PropertyDescription
fontSizeText size — typically large (60–120pt) for a single centered mark.
fontColorText color.
bold / italicBoolean.
fontFont family — useful for Helvetica-BoldOblique italic-bold combos.
opacity0.01.0 translucency. Most watermarks use 0.050.30.
{
"styles": {
"draft": { "fontSize": 96, "bold": true, "fontColor": "#94A3B8", "opacity": 0.25 },
"verified": { "fontSize": 80, "bold": true, "fontColor": "#15803D", "opacity": 0.35 },
"logoFaint": { "opacity": 0.15 }
}
}

What's next

  • Canvas — for diagrams and decorative chrome that should reserve flow space (or render at fixed page coordinates) instead of overlaying every page.
  • Columns — multi-column layouts inside the document body.