PDF Preview Guide
This guide covers how to display PDF documents inline using pdf-preview code blocks.
Overview
Section titled “Overview”The pdf-preview block renders PDF files inline in chat messages — showing the first page with an expand button for full multi-page navigation in a fullscreen overlay.
| Format | Best For | Rendering |
|---|---|---|
pdf-preview block |
PDF documents, reports, invoices | First page inline, full navigation in fullscreen |
html-preview block |
Emails, newsletters, styled HTML | Sandboxed iframe with full CSS |
image-preview block |
Screenshots, captures, visual diffs | Inline fit-to-container + fullscreen viewer |
datatable/spreadsheet |
Structured data, tables | Interactive sortable/filterable tables |
Key principle: Unlike html-preview which needs transform_data to extract HTML, PDFs are already files on disk. Just reference the file path directly — no extraction step needed.
When to Use
Section titled “When to Use”Use pdf-preview when:
- Tool results reference a PDF file — Read tool, file downloads, API responses with PDF paths
- Generated reports — Scripts or tools that produce PDF output
- Downloaded documents — PDFs fetched from APIs or saved from web
- User asks to view a PDF — Any PDF file the user mentions or references
Do NOT use pdf-preview when:
- Content is structured data — use
datatableorspreadsheetinstead - Content is HTML — use
html-previewinstead - The PDF is a code/text file — just read it and present as markdown
- The user wants to extract text from the PDF — use the Read tool’s PDF support instead
Basic Usage
Section titled “Basic Usage”Single Item
Section titled “Single Item”```pdf-preview{ "src": "/absolute/path/to/file.pdf", "title": "Q4 Financial Report"}```Multiple Items (Tabs)
Section titled “Multiple Items (Tabs)”When you have multiple related PDFs (e.g., quarterly reports, contract versions), use the items array. A tab bar appears below the header for switching between items.
```pdf-preview{ "title": "Quarterly Reports", "items": [ { "src": "/path/to/q1-report.pdf", "label": "Q1" }, { "src": "/path/to/q2-report.pdf", "label": "Q2" }, { "src": "/path/to/q3-report.pdf", "label": "Q3" } ]}```Content loads lazily on tab switch and is cached once loaded.
Config Fields
Section titled “Config Fields”| Field | Required | Type | Description |
|---|---|---|---|
src |
Yes* | string | Absolute path to the PDF file on disk (single item mode) |
title |
No | string | Display title shown in the header bar (defaults to “PDF Preview”) |
items |
Yes* | array | Array of items with src and optional label (multi-item mode) |
items[].src |
Yes | string | Absolute path to the PDF file |
items[].label |
No | string | Tab label (defaults to “Item 1”, “Item 2”, etc.) |
*Either src (single) or items (multiple) is required. If both are present, items takes precedence.
Important: The src path must be an absolute path. Use the exact path from tool results or construct one using known directory paths.
Common Patterns
Section titled “Common Patterns”After Using the Read Tool on a PDF
Section titled “After Using the Read Tool on a PDF”When the Read tool reads a PDF, the file already exists on disk. Reference it directly:
```pdf-preview{ "src": "/Users/john/Documents/report.pdf", "title": "Annual Report 2025"}```PDF from API Download
Section titled “PDF from API Download”When a tool downloads a PDF (e.g., from an API response that returns binary data):
- The file is typically saved to the session downloads folder
- Reference the saved path in the
pdf-previewblock
```pdf-preview{ "src": "/absolute/path/to/downloaded/invoice.pdf", "title": "Invoice #12345"}```PDF Generated by a Script
Section titled “PDF Generated by a Script”When running a Python script that generates a PDF (e.g., with reportlab, fpdf2, or weasyprint):
# Example: generate PDF with fpdf2from fpdf import FPDFimport sys
pdf = FPDF()pdf.add_page()pdf.set_font('Helvetica', size=16)pdf.cell(text='Hello World')pdf.output(sys.argv[-1])Call via transform_data, then reference the output:
```pdf-preview{ "src": "/absolute/path/from/transform_data/report.pdf", "title": "Generated Report"}```PDF from User’s Filesystem
Section titled “PDF from User’s Filesystem”When the user references a PDF they have locally:
```pdf-preview{ "src": "/Users/john/Downloads/contract.pdf", "title": "Service Agreement"}```Rendering Behavior
Section titled “Rendering Behavior”Inline Preview
Section titled “Inline Preview”- Shows first page only at max-height 400px with bottom fade gradient
- White background — standard for PDF documents
- Expand button (top-right corner, visible on hover) opens fullscreen view
- Header bar shows FileText icon and title
- No pagination controls inline — use fullscreen for multi-page navigation
Fullscreen Overlay
Section titled “Fullscreen Overlay”- Full page-by-page navigation with prev/next buttons
- Page counter showing “Page X / Y”
- Copy path button copies the file path to clipboard
- “PDF” badge in header identifies the content type
- Text selection and annotation layers enabled for interactivity
Performance Notes
Section titled “Performance Notes”- PDFs are loaded as binary data (
Uint8Array) via IPC — efficient even for large files - The pdf.js worker handles decoding and rendering in a background thread
- Inline preview only renders page 1 — remaining pages load on-demand in fullscreen
- The file object is memoized to prevent unnecessary re-renders
Integration with Read Tool
Section titled “Integration with Read Tool”The Read tool already supports reading PDFs with the pages parameter. Use pdf-preview for visual rendering and Read for text extraction:
| Goal | Tool |
|---|---|
| See the PDF visually | pdf-preview code block |
| Extract text content | Read tool with pages parameter |
| Both | Use Read to extract text, then show pdf-preview for visual reference |
Decision Tree
Section titled “Decision Tree”Does the user want to SEE the document? → YES: Use pdf-preview (visual fidelity matters) → NO: Extract text with Read tool and present as markdown
Is the content already a PDF file on disk? → YES: Use pdf-preview with direct file path → NO: Is it HTML? → Use html-preview Is it data? → Use datatable/spreadsheet Is it binary from an API? → Save to file first, then pdf-previewTroubleshooting
Section titled “Troubleshooting”“Loading…” shown indefinitely
Section titled ““Loading…” shown indefinitely”- The
"src"path must be an absolute path — not relative - Verify the file exists at the specified path
- Check that the file is actually a PDF (not renamed HTML, etc.)
Blank/white preview
Section titled “Blank/white preview”- The PDF file may be empty or corrupted
- Some encrypted PDFs require a password — pdf.js cannot render these
- Try opening the file with a system PDF viewer to verify it’s valid
First page looks cut off
Section titled “First page looks cut off”- The inline preview has a max-height of 400px — this is by design
- Click the expand button (top-right) for full-page rendering
- In fullscreen, the page renders at full size with scrolling
“Failed to render PDF” error
Section titled ““Failed to render PDF” error”- The file may not be a valid PDF
- Very large PDFs (100MB+) may fail to load — consider extracting specific pages first
- Scanned PDFs render as images — this is expected behavior
Fullscreen overlay shows different content
Section titled “Fullscreen overlay shows different content”- The overlay loads the PDF independently from the file path
- If the file was modified between inline load and fullscreen open, content may differ
Text not selectable in inline preview
Section titled “Text not selectable in inline preview”- Text selection is intentionally disabled in the inline preview (renders without text layer for performance)
- Open fullscreen view for text selection support — the text layer is enabled there