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:
| Mode | What it does | Output |
|---|---|---|
| EMBED | Extracts selected pages, rasterizes to JPEG, embeds as inline images | Pixel images (not searchable text) |
| APPEND | Merges a full PDF as native pages at the end of the document | Original 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: trueProperties
| Property | Type | Default | Required | Description |
|---|---|---|---|---|
type | "image" or "figure" | — | Yes | Standard image block type. |
src | string | — | Yes | Path to the PDF. Relative asset path (for example, "Media/report.pdf") or HTTPS URL. |
mode | "embed" | — | Yes | Must be "embed" to activate PDF extraction. Without it, the .pdf file is ignored. |
pageRange | string | "1" | No | Which pages to extract. See page range syntax below. |
extractDpi | number | 150 | No | Render resolution. 72 = screen, 150 = balanced, 300 = print quality. |
extractQuality | number | 80 | No | JPEG compression quality (1–100). Lower equals smaller file, more artifacts. |
width | number | 540 | No | Target column width in points. |
columns | number | 2 | No | When multiple pages are extracted, arrange them in a grid with this many columns. |
show_captions | boolean | false | No | Show "Page N" captions below each image in multi-page grid. |
Page Range Syntax
| Value | Extracts |
|---|---|
"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
imageblock with a JPEG data URI. - Multiple pages: replaces the block with an
image_gridcontaining one image per page.
DPI and File Size
The rendered pixel width is: (width ÷ 72) × extractDpi
extractDpi | Pixel width (at 540 pt) | Typical JPEG size per page |
|---|---|---|
| 72 | 540 px | ~50–100 KB |
| 150 | 1,125 px | ~200–500 KB |
| 300 | 2,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: trueProperties
| Property | Type | Default | Required | Description |
|---|---|---|---|---|
type | "pdf_appendix" | — | Yes | Block type identifier. |
src | string | — | Yes | PDF path: relative asset path or HTTPS URL. |
library | "assets" | "assets" | No | Asset library name. |
title | string | — | No | When set, a title page is generated and inserted before the appended pages. |
pageNumbers | boolean | false | No | When 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 outputWhich Mode Handles Fonts Better?
The two modes handle fonts very differently. Choose based on your document's fonts and your use case.
| Scenario | APPEND | EMBED |
|---|---|---|
| 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 case | Technical docs, manuals, legal documents | Photo 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: 85Example 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: trueExample 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: truesupplementary_Annex Block Reference
Complete property reference for the supplementary_Annex block type.
Data Binding
| Property | Type | Required | Description |
|---|---|---|---|
data_source | string | Yes | Variable reference to the data array, for example, "{{Lines}}". Must resolve to an array. |
notes_field | string or string[] | No | Field name(s) containing notes. When omitted, auto-detected by heuristic. |
images_field | string or string[] | No | Field name(s) containing image URLs. When omitted, auto-detected by heuristic. |
id_field | string | No | Field name for the item identifier (for example, "No."). Used in headers and table of contents. |
name_field | string | No | Field name for the item description (for example, "Description"). Used in headers. |
children_fields | string[] | No | Field names containing nested child arrays for hierarchical data flattening. |
Layout Options
| Property | Type | Default | Description |
|---|---|---|---|
showDivider | boolean | false | Render a thin horizontal rule between consecutive items. |
includeInToc | boolean | false | Add annex items to the document's table of contents. |
sectionNumbering | boolean | false | Show 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
| Property | Type | Default | Description |
|---|---|---|---|
type | "sub_header" | — | Block type. |
text | string | — | Header text. Supports {{item.id}}, {{item.name}}, and payload variables. |
subtitle | string | — | Optional second line. Supports variables and format pipes (` |
style | string | — | Visual style. Options: variant_blue_bar, variant_green_bar, etc. |
repeat_notes
| Property | Type | Default | Description |
|---|---|---|---|
type | "repeat_notes" | — | Block type. |
source | string | — | Variable reference to notes array, for example, "{{item.notes}}". |
style | string | — | Paragraph style. Options: paragraph_block, compact, etc. |
image_grid
| Property | Type | Default | Description |
|---|---|---|---|
type | "image_grid" | — | Block type. |
source | string | — | Variable reference to images array, for example, "{{item.images}}". |
columns | number | 2 | Images per row. |
target_dpi | number | 150 | Downsample DPI. Higher equals sharper, larger files. Also controls PDF page render resolution. |
image_quality | number | 80 | JPEG quality (1–100). Also controls PDF page JPEG quality. |
show_captions | boolean | true | Show captions below each image. |
caption | string | — | Caption template. Supports {{item.id}}, {{item.name}}, etc. |
Image Path Formats
All image and PDF asset paths can use any of these formats:
| Format | Example | When 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.
Enable via payload (recommended)
{
"features": {
"supplementaryAnnex": true
}
}Enable via template settings (default for all renders)
{
"templateSettings": {
"supplementaryAnnex": {
"enabled": true
}
}
}Priority: Payload features.supplementaryAnnex overrides templateSettings.supplementaryAnnex.enabled.
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| PDF embed shows placeholder | Required dependencies not installed | These are auto-installed as dependencies. Check node_modules is complete. |
| PDF embed is blank or returns null | mode: "embed" missing from the block | Add mode: "embed" to the block. Without it, the .pdf src is ignored. |
| PDF in annex grid shows placeholder | File extension is not .pdf | Ensure the URL ends with .pdf (query strings like ?sv=... are fine). |
| Appendix pages not appearing | pdf_appendix block in sections but no output | Verify the PDF path is correct and the file is accessible from the assets library. |
| Large output file size | High DPI or quality on many pages | Reduce extractDpi to 150 and extractQuality to 75–80. |
| Annex section missing entirely | Feature flag not set | Add "features": { "supplementaryAnnex": true } to the payload. |
Image Support Guide
Comprehensive guide to image rendering options in VaultPDF, including standalone images, image grids, and inline images in tables and cards. Supports both SharePoint asset paths and Base64 data URIs.
Icon Reference
Complete reference of valid icon names available for use in VaultPDF documents. Includes status, information, content, system, and form control icons.