Generating PDFs with React-PDF
CRITICAL REQUIREMENTS
- Fonts MUST be local files - Remote font URLs (http/https) do NOT work. Always download fonts to local files before using them.
- Wrap async code in IIFE - Top-level await causes errors. Always use
(async () => { ... })()pattern. - Disable hyphenation for custom fonts - Custom fonts lack hyphenation dictionaries and may
crash or break words incorrectly. Always call
Font.registerHyphenationCallback((word) => [word]);after registering custom fonts.
Files
references/google-fonts.txt- Metadata for ~65 popular Google Fonts with TrueType URLs. Each line is a font variant in tab-separated format:font name,style,category,weight,url.references/components.md- Full component API reference and supported CSS propertiesassets/example-template.tsx- Minimal working example demonstrating fixed footers, page numbers, and unbreakable content. Read this before starting to understand the basic patterns. Note: not all APIs are shown here — always refer to the docs andreferences/components.mdfor the full API.
Prerequisites
tsx runs TypeScript + JSX files directly via Node with no config — no tsconfig.json needed. It
uses esbuild under the hood and handles JSX transformation automatically.
Core Components
- Document: Root component (metadata, settings)
- Page: Individual pages (A4, Letter, or custom dimensions)
- View: Container component (similar to div)
- Text: Text content, supports nesting for inline styling
- Image: Embed images (JPG, PNG, base64)
- Link: Clickable hyperlinks (external or internal)
- Note: Annotation notes
- Canvas: Freeform drawing with pdfkit methods
- Svg: Vector graphics (Circle, Rect, Path, Line, Polygon, etc.)
- StyleSheet: Create reusable styles
For full component props and CSS properties, see references/components.md [blocked].
Basic Example
Running Scripts
PDF generation scripts use JSX, which Node cannot run directly. Use tsx to execute them:
npx tsx works without installing tsx globally — it downloads on demand. If tsx is installed as a
dev dependency (npm install -D tsx), it runs instantly without the npx download step.
Always wrap rendering in async IIFE:
Previewing PDFs
To visually inspect generated PDFs, convert pages to images. Try pdftoppm first (often
pre-installed), fall back to Python's PyMuPDF if unavailable.
Option 1: pdftoppm (poppler-utils) — preferred, no install needed in many environments:
Option 2: PyMuPDF (Python) — fallback if pdftoppm is not available:
Rendering Methods
Styling
Three methods: StyleSheet.create(), inline objects, or mixed arrays.
Supported Units
pt (default, 72 DPI), in, mm, cm, %, vw, vh
Common Style Properties
Images
Local files are most reliable. Remote URLs may fail due to network/CORS issues.
SVG files cannot be used as Image sources. Read the SVG source and recreate using react-pdf Svg components.
SVG Graphics
Using Icons
Read SVG source from icon libraries and convert to react-pdf Svg components:
Links and Navigation
Dynamic Content and Page Numbers
Fixed Headers/Footers
Page Breaks and Wrapping
Custom Fonts
CRITICAL: All font sources MUST be local file paths. Remote URLs do not work.
Built-in fonts: Courier, Helvetica, Times-Roman (each with Bold, Italic/Oblique variants)
Font weight values: thin (100), ultralight (200), light (300), normal (400), medium (500), semibold (600), bold (700), ultrabold (800), heavy (900)
Google Fonts
Use references/google-fonts.txt to find font URLs, then download locally:
If file shows "HTML document" or "ASCII text", the download failed. Try a different URL or search
GitHub for the font's official repo with TTF files.
Emoji
Emoji won't render in PDFs unless you register an emoji source. Install twemoji-emojis to get
local Twemoji PNG assets — no internet needed at render time.
Then use emoji directly in Text: <Text>Hello 🚀🎉</Text>
Other Features
Best Practices
- Use
StyleSheet.create()— define styles once and reuse - Compress images before embedding, use
cache={true}for remote images - Test page breaks — content may flow differently than expected
- Prefer flexbox over absolute positioning
- Use
fixedprop for headers/footers on every page - Use
debug={true}to visualize element boundaries - Wrap rendering in try-catch blocks
Common Issues
Text overflow: <Text style={{ width: 200, maxLines: 3, textOverflow: "ellipsis" }}>...</Text>
Missing fonts: Download locally and register with local file paths. Remote URLs will NOT work.
Unexpected page breaks: Use wrap={false} to keep content together, or <View break /> to
force breaks.

