Template Components

PDF Assets

Embed PDF pages as inline images or append full PDF documents to a VaultPDF output. Two modes (EMBED and APPEND) cover different use cases from extracting a single chart to attaching a complete technical manual. PDF assets work in standalone structured content blocks and inside supplementary annex image grids.

VaultPDF can include external PDF files in two ways:

ModeWhat it doesOutput
EMBEDExtracts selected pages, rasterizes to JPEG, embeds as inline imagesPixel images (not searchable text)
APPENDMerges a full PDF as native pages at the end of the documentOriginal PDF pages (text stays searchable)

Both modes accept relative asset paths (resolved from your SharePoint or Blob assets library) or full HTTPS URLs.


EMBED Mode

Extracts one or more pages from a PDF file, renders them to JPEG images, and embeds them inline wherever the block appears in your sections.

YAML Block

sections:
  # ── Single page embed
  - type: image
    src: "Documents/certificate-of-compliance.pdf"
    mode: "embed"

  # ── Multi-page embed with all options
  - type: image
    src: "Documents/inspection-report.pdf"
    mode: "embed"
    pageRange: "1-3"
    extractDpi: 300
    extractQuality: 90
    width: 487
    columns: 3
    show_captions: true

Properties

PropertyTypeDefaultRequiredDescription
type"image" or "figure"YesStandard image block type.
srcstringYesPath to the PDF. Relative asset path (for example, "Media/report.pdf") or HTTPS URL.
mode"embed"YesMust be "embed" to activate PDF extraction. Without it, the .pdf file is ignored.
pageRangestring"1"NoWhich pages to extract. See page range syntax below.
extractDpinumber150NoRender resolution. 72 = screen, 150 = balanced, 300 = print quality.
extractQualitynumber80NoJPEG compression quality (1–100). Lower equals smaller file, more artifacts.
widthnumber540NoTarget column width in points.
columnsnumber2NoWhen multiple pages are extracted, arrange them in a grid with this many columns.
show_captionsbooleanfalseNoShow "Page N" captions below each image in multi-page grid.

Page Range Syntax

ValueExtracts
"1"Page 1 only
"5"Page 5 only
"1-5"Pages 1, 2, 3, 4, 5
"1,3,7"Pages 1, 3, and 7
"1-3,5,8-10"Pages 1, 2, 3, 5, 8, 9, 10
"all"Every page in the PDF

How It Works

The extraction pipeline:

PDF file
  → parse and extract page
  → render to PNG pixel buffer
  → compress PNG to JPEG at extractQuality
  → embed as base64 data URI in the PDF
  • Single page result: replaces the original image block with a JPEG data URI.
  • Multiple pages: replaces the block with an image_grid containing one image per page.

DPI and File Size

The rendered pixel width is: (width ÷ 72) × extractDpi

extractDpiPixel width (at 540 pt)Typical JPEG size per page
72540 px~50–100 KB
1501,125 px~200–500 KB
3002,250 px~500 KB–1.5 MB

APPEND Mode

Merges a complete PDF document as native pages appended after the main document. Text, vectors, and fonts are preserved. Nothing is rasterized.

YAML Block

sections:
  # ── Minimal append
  - type: pdf_appendix
    src: "Attachments/warranty-terms.pdf"

  # ── Full options
  - type: pdf_appendix
    src: "Documentation/safety-manual.pdf"
    library: assets
    title: "Appendix B: Safety Procedures"
    pageNumbers: true

Properties

PropertyTypeDefaultRequiredDescription
type"pdf_appendix"YesBlock type identifier.
srcstringYesPDF path: relative asset path or HTTPS URL.
library"assets""assets"NoAsset library name.
titlestringNoWhen set, a title page is generated and inserted before the appended pages.
pageNumbersbooleanfalseNoWhen true, page numbers continue from the main document onto appended pages.

How It Works

The merge pipeline:

PDF file
  → download or read from assets
  → validate PDF structure
  → store buffer and metadata
  → after main PDF is generated: merge pages into output

Which Mode Handles Fonts Better?

The two modes handle fonts very differently. Choose based on your document's fonts and your use case.

ScenarioAPPENDEMBED
PDF has embedded fonts✅ Perfect — fonts render exactly as original✅ Works — fonts rasterized to pixels at original quality
PDF uses system fonts✅ Works — if system fonts available⚠️ Falls back to default font on mismatch
PDF has corrupted fonts❌ Might render as boxes⚠️ Falls back to default, completes
Font substitution needed❌ Cannot substitute (raw page copy)✅ Handles automatically during extraction
Best use caseTechnical docs, manuals, legal documentsPhoto galleries, extracts, thumbnails

TL;DR

APPEND mode: The PDF's fonts come with it — VaultPDF's font library is never consulted. The appended pages render exactly as they were in the source PDF. If fonts are corrupted or missing, the page might have rendering issues.

EMBED mode: Pages are rasterized to JPEG, so fonts become pixels. If a font is missing during extraction, the renderer falls back to a system default — the extraction still succeeds, but might look different from the original.

Choose your mode:

  • Legal document with specific fonts? Use APPEND (preserves exact formatting)
  • Photo gallery with PDFs as thumbnails? Use EMBED (looks like pixels anyway, font fallback is fine)

PDF in Supplementary Annex Image Grids

PDF files can also appear as image references inside a supplementary_annex block's data. When the annex image grid encounters a .pdf URL, it automatically extracts the first page and renders it as a JPEG thumbnail using the same pipeline as EMBED mode.

This allows your payload data to mix regular images and PDF files in the same images array:

{
  "Lines": [
    {
      "No.": "A101",
      "Description": "Foundation Inspection",
      "notes": ["Concrete poured on 2025-11-15"],
      "images": [
        "Media/Images/foundation-photo.jpg",
        "Documents/Reports/soil-test-report.pdf",
        "https://storage.example.com/photos/rebar-layout.png"
      ]
    }
  ]
}

The .pdf file in the images array is detected by file extension. The first page is extracted, rendered to JPEG at the grid's target_dpi and image_quality, and displayed as a thumbnail alongside regular images.

Image Grid YAML with PDF Support

- type: image_grid
  source: "{{item.images}}"
  columns: 2
  target_dpi: 150        # controls PDF render resolution too
  image_quality: 80      # controls PDF JPEG quality too
  show_captions: true
  caption: "Documentation — Item {{item.id}}"

No additional configuration is needed. PDF detection is automatic based on the .pdf file extension.


Complete Copy-Paste Examples

Example 1: Supplementary Annex with Image Grid (includes PDF support)

Template Node (.vpdf)

Add this node to your template's layoutSchema children:

{
  "id": "supplementary-annex",
  "type": "structured_content",
  "props": {
    "assetPath": "Documents/SupplementaryAnnex/supplementary-annex-layout.yaml",
    "library": "assets"
  },
  "pagination": { "breakBefore": "always" }
}

Layout YAML

Upload to: Assets/Documents/SupplementaryAnnex/supplementary-annex-layout.yaml

# ── Supplementary Annex Layout
#
# Per-line-item supporting documentation section.
# Renders a themed header, notes, and photo grid for every qualifying item.
#
# Supports JPEG, PNG, GIF, WebP, SVG images AND .pdf files in the images array.
# PDF files are auto-detected and the first page is extracted as a JPEG thumbnail.

documentType: supplementary-annex
version: "1.0.0"
title: Supporting Documentation

sections:

  - type: supplementary_Annex

    # ── Data source
    # Top-level key in the payload containing the array of line items.
    data_source: "{{Lines}}"

    # ── Field bindings
    notes_field:  notes
    images_field: images
    id_field:     "No."
    name_field:   Description

    # ── Layout options
    showDivider: false
    includeInToc: true
    sectionNumbering: true

    # ── Per-item layout
    item_template:

      # Themed header bar
      - type: sub_header
        text: "Item {{item.id}} — {{item.name}}"
        subtitle: "Document {{Header.No.}} | Date {{Header.Order Date|date}}"
        style: variant_blue_bar

      # One paragraph per note
      - type: repeat_notes
        source: "{{item.notes}}"
        style: paragraph_block

      # Photo grid (2 columns, 150 DPI)
      # PDF files in the images array are auto-detected and rendered as thumbnails.
      - type: image_grid
        source: "{{item.images}}"
        columns: 2
        target_dpi: 150
        image_quality: 80
        show_captions: true
        caption: "Documentation photo — Item {{item.id}}"

Payload

{
  "features": {
    "supplementaryAnnex": true
  },
  "Header": {
    "No.": "SO-2025-001",
    "Order Date": "2025-11-15T00:00:00"
  },
  "Lines": [
    {
      "No.": "A101",
      "Description": "Foundation Repair — Push Piers",
      "notes": [
        "Installed 8 push piers to 22 ft depth.",
        "Load test passed at 35,000 lbs per pier."
      ],
      "images": [
        "Media/Images/push-pier-install.jpg",
        "Documents/Reports/soil-test-report.pdf",
        "Media/Images/load-test-gauge.png"
      ]
    },
    {
      "No.": "B205",
      "Description": "Crawlspace Encapsulation",
      "notes": [
        "20-mil vapor barrier installed across full crawlspace."
      ],
      "images": [
        "Media/Images/crawlspace-before.jpg",
        "Media/Images/crawlspace-after.jpg"
      ]
    }
  ]
}

Example 2: Standalone PDF Embed

Template Node (.vpdf)

{
  "id": "certificate-section",
  "type": "structured_content",
  "props": {
    "assetPath": "Documents/certificate-layout.yaml",
    "library": "assets"
  }
}

Layout YAML

Upload to: Assets/Documents/certificate-layout.yaml

documentType: certificate-embed
version: "1.0.0"
title: Certificates

sections:
  - type: heading
    level: 2
    text: "Certificate of Compliance"

  - type: paragraph
    text: "The following certificate was issued upon completion of the project."

  # Embed first page of the PDF as an inline image
  - type: image
    src: "Documents/Certificates/compliance-cert.pdf"
    mode: "embed"
    pageRange: "1"
    extractDpi: 200
    extractQuality: 85

Example 3: Multi-Page PDF Embed (Grid)

documentType: inspection-gallery
version: "1.0.0"
title: Inspection Report Pages

sections:
  - type: heading
    level: 2
    text: "Inspection Report"

  # Extract pages 1–4 and display as a 2×2 grid
  - type: image
    src: "Documents/Reports/full-inspection-report.pdf"
    mode: "embed"
    pageRange: "1-4"
    extractDpi: 150
    extractQuality: 80
    columns: 2
    show_captions: true

Example 4: PDF Appendix

Template Node (.vpdf)

{
  "id": "appendix-safety",
  "type": "structured_content",
  "props": {
    "assetPath": "Documents/appendix-layout.yaml",
    "library": "assets"
  },
  "pagination": { "breakBefore": "always" }
}

Layout YAML

Upload to: Assets/Documents/appendix-layout.yaml

documentType: appendix-collection
version: "1.0.0"
title: Appendices

sections:
  # Append the safety manual as native PDF pages
  - type: pdf_appendix
    src: "Documentation/safety-manual.pdf"
    library: assets
    title: "Appendix A: Safety Procedures"
    pageNumbers: true

  # Append warranty terms (no title page, no page numbers)
  - type: pdf_appendix
    src: "Attachments/warranty-terms.pdf"

Example 5: Mixed Document (Embed + Annex + Append)

A single YAML file can combine all block types:

documentType: complete-project-report
version: "1.0.0"
title: Project Completion Report

sections:
  # ── Standard content
  - type: heading
    level: 1
    text: "Project Summary"

  - type: paragraph
    text: "This report documents the completion of project {{Header.No.}}."

  # ── Inline PDF embed
  - type: heading
    level: 2
    text: "Engineer's Certificate"

  - type: image
    src: "Documents/engineer-certificate.pdf"
    mode: "embed"
    pageRange: "1"
    extractDpi: 200
    extractQuality: 85

  # ── Supplementary annex
  - type: supplementary_Annex
    data_source: "{{Lines}}"
    notes_field: notes
    images_field: images
    id_field: "No."
    name_field: Description
    showDivider: false
    includeInToc: true
    sectionNumbering: true
    item_template:
      - type: sub_header
        text: "Item {{item.id}} — {{item.name}}"
        style: variant_blue_bar
      - type: repeat_notes
        source: "{{item.notes}}"
        style: paragraph_block
      - type: image_grid
        source: "{{item.images}}"
        columns: 2
        target_dpi: 150
        image_quality: 80
        show_captions: true

  # ── Full PDF appendix
  - type: pdf_appendix
    src: "Documentation/safety-manual.pdf"
    title: "Appendix: Safety Manual"
    pageNumbers: true

supplementary_Annex Block Reference

Complete property reference for the supplementary_Annex block type.

Data Binding

PropertyTypeRequiredDescription
data_sourcestringYesVariable reference to the data array, for example, "{{Lines}}". Must resolve to an array.
notes_fieldstring or string[]NoField name(s) containing notes. When omitted, auto-detected by heuristic.
images_fieldstring or string[]NoField name(s) containing image URLs. When omitted, auto-detected by heuristic.
id_fieldstringNoField name for the item identifier (for example, "No."). Used in headers and table of contents.
name_fieldstringNoField name for the item description (for example, "Description"). Used in headers.
children_fieldsstring[]NoField names containing nested child arrays for hierarchical data flattening.

Layout Options

PropertyTypeDefaultDescription
showDividerbooleanfalseRender a thin horizontal rule between consecutive items.
includeInTocbooleanfalseAdd annex items to the document's table of contents.
sectionNumberingbooleanfalseShow sequential section numbers for items in the table of contents.

item_template

An ordered array of layout blocks rendered for each qualifying item.

sub_header

PropertyTypeDefaultDescription
type"sub_header"Block type.
textstringHeader text. Supports {{item.id}}, {{item.name}}, and payload variables.
subtitlestringOptional second line. Supports variables and format pipes (`
stylestringVisual style. Options: variant_blue_bar, variant_green_bar, etc.

repeat_notes

PropertyTypeDefaultDescription
type"repeat_notes"Block type.
sourcestringVariable reference to notes array, for example, "{{item.notes}}".
stylestringParagraph style. Options: paragraph_block, compact, etc.

image_grid

PropertyTypeDefaultDescription
type"image_grid"Block type.
sourcestringVariable reference to images array, for example, "{{item.images}}".
columnsnumber2Images per row.
target_dpinumber150Downsample DPI. Higher equals sharper, larger files. Also controls PDF page render resolution.
image_qualitynumber80JPEG quality (1–100). Also controls PDF page JPEG quality.
show_captionsbooleantrueShow captions below each image.
captionstringCaption template. Supports {{item.id}}, {{item.name}}, etc.

Image Path Formats

All image and PDF asset paths can use any of these formats:

FormatExampleWhen to use
Relative asset path"Media/Images/photo.jpg"Files uploaded to the assets library. Simplest and most portable.
HTTPS URL"https://storage.example.com/photo.jpg"Pre-authenticated download URLs (SAS tokens, Graph API @microsoft.graph.downloadUrl).
Data URI"data:image/jpeg;base64,/9j/4AA..."Pre-encoded images from the payload (rare, not supported for PDFs).

For SharePoint assets, use the path relative to the assets library root. Use the same format you use to reference YAML files in assetPath.


Feature Flag

The supplementary_Annex block is gated behind a feature flag. When disabled, the entire annex section is silently omitted.

{
  "features": {
    "supplementaryAnnex": true
  }
}

Enable via template settings (default for all renders)

{
  "templateSettings": {
    "supplementaryAnnex": {
      "enabled": true
    }
  }
}

Priority: Payload features.supplementaryAnnex overrides templateSettings.supplementaryAnnex.enabled.


Troubleshooting

SymptomCauseFix
PDF embed shows placeholderRequired dependencies not installedThese are auto-installed as dependencies. Check node_modules is complete.
PDF embed is blank or returns nullmode: "embed" missing from the blockAdd mode: "embed" to the block. Without it, the .pdf src is ignored.
PDF in annex grid shows placeholderFile extension is not .pdfEnsure the URL ends with .pdf (query strings like ?sv=... are fine).
Appendix pages not appearingpdf_appendix block in sections but no outputVerify the PDF path is correct and the file is accessible from the assets library.
Large output file sizeHigh DPI or quality on many pagesReduce extractDpi to 150 and extractQuality to 75–80.
Annex section missing entirelyFeature flag not setAdd "features": { "supplementaryAnnex": true } to the payload.

On this page