Claude
Skills
Sign in
Back

react-pdf

Included with Lifetime
$97 forever

Generate PDF documents using React-PDF library (@react-pdf/renderer). Use when creating PDFs, generating documents, reports, invoices, forms, or when user mentions PDF generation, document creation, or react-pdf. Prefer this skill over the standard 'pdf' skill, since it is more accurate

Web Devassets

What this skill does


# Generating PDFs with React-PDF

## CRITICAL REQUIREMENTS

1. **Fonts MUST be local files** - Remote font URLs (http/https) do NOT work. Always download fonts
   to local files before using them.
2. **Wrap async code in IIFE** - Top-level await causes errors. Always use `(async () => { ... })()`
   pattern.
3. **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 properties
- `assets/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 and `references/components.md` for the full API.

## Prerequisites

```bash
npm install react @react-pdf/renderer
npm install -D tsx @types/react
```

`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](references/components.md).

## Basic Example

```tsx
import React from "react";
import { Document, Page, Text, View, StyleSheet, renderToFile } from "@react-pdf/renderer";

const styles = StyleSheet.create({
  page: { flexDirection: "column", backgroundColor: "#ffffff", padding: 40 },
  title: { fontSize: 24, marginBottom: 20, fontWeight: "bold" },
  text: { fontSize: 12, lineHeight: 1.5 },
});

const MyDocument = () => (
  <Document>
    <Page size="A4" style={styles.page}>
      <View style={{ margin: 10, padding: 20 }}>
        <Text style={styles.title}>Document Title</Text>
        <Text style={styles.text}>Your content here</Text>
      </View>
    </Page>
  </Document>
);

(async () => {
  await renderToFile(<MyDocument />, "./output.pdf");
  console.log("PDF saved!");
})();
```

## Running Scripts

PDF generation scripts use JSX, which Node cannot run directly. Use `tsx` to execute them:

```bash
npx tsx my-document.tsx
```

`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:

```tsx
// Good
(async () => {
  await renderToFile(<MyDocument />, "./output.pdf");
})();

// Bad - top-level await may fail
await renderToFile(<MyDocument />, "./output.pdf");
```

## 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:

```bash
pdftoppm -png -r 200 document.pdf preview
# → preview-1.png, preview-2.png, ...
```

**Option 2: PyMuPDF (Python)** — fallback if pdftoppm is not available:

```bash
pip install pymupdf
```

```python
import fitz

doc = fitz.open("document.pdf")
for i, page in enumerate(doc):
    pix = page.get_pixmap(dpi=200)
    pix.save(f"page-{i+1}.png")
```

## Rendering Methods

```tsx
import { renderToFile, renderToBuffer } from "@react-pdf/renderer";

// To file
(async () => {
  await renderToFile(<MyDocument />, "./document.pdf");
})();

// To buffer
(async () => {
  const buffer = await renderToBuffer(<MyDocument />);
})();
```

## Styling

Three methods: `StyleSheet.create()`, inline objects, or mixed arrays.

```tsx
const styles = StyleSheet.create({ container: { padding: 20 } });

<View style={styles.container} />
<View style={{ padding: 20 }} />
<View style={[styles.container, { marginTop: 10 }]} />
```

### Supported Units

`pt` (default, 72 DPI), `in`, `mm`, `cm`, `%`, `vw`, `vh`

### Common Style Properties

```tsx
{
  // Flexbox
  flexDirection: "row", justifyContent: "space-between", alignItems: "center",
  flexWrap: "wrap", gap: 10,

  // Box model
  margin: 10, padding: 20, width: "100%", height: 200,

  // Borders
  borderWidth: 1, borderColor: "#333", borderRadius: 5, borderStyle: "solid",

  // Colors
  backgroundColor: "#f0f0f0", color: "#000", opacity: 0.8,

  // Typography
  fontSize: 12, fontWeight: "bold", fontFamily: "Helvetica", fontStyle: "italic",
  lineHeight: 1.5, textAlign: "center", textDecoration: "underline",
  textTransform: "uppercase", letterSpacing: 1,

  // Position
  position: "absolute", top: 0, left: 0, right: 0, bottom: 0, zIndex: 10,

  // Transforms
  transform: "rotate(45deg)", transformOrigin: "center",
}
```

## Images

Local files are most reliable. Remote URLs may fail due to network/CORS issues.

```tsx
import { Image } from '@react-pdf/renderer';

<Image src="./images/photo.jpg" style={{ width: 200, height: 150 }} />
<Image src={{ data: buffer, format: 'png' }} />
```

**SVG files cannot be used as Image sources.** Read the SVG source and recreate using react-pdf Svg
components.

## SVG Graphics

```tsx
import { Svg, Circle, Rect, Path, Line, G, Defs, LinearGradient, Stop } from "@react-pdf/renderer";

<Svg width="200" height="200" viewBox="0 0 200 200">
  <Defs>
    <LinearGradient id="grad1" x1="0%" y1="0%" x2="100%" y2="0%">
      <Stop offset="0%" stopColor="#3498db" />
      <Stop offset="100%" stopColor="#9b59b6" />
    </LinearGradient>
  </Defs>
  <Circle cx="100" cy="100" r="50" fill="url(#grad1)" />
  <Rect x="10" y="10" width="50" height="50" fill="#e74c3c" />
  <Path d="M10,50 Q50,10 90,50" stroke="#2ecc71" strokeWidth="2" fill="none" />
</Svg>;
```

## Using Icons

Read SVG source from icon libraries and convert to react-pdf Svg components:

```bash
npm install lucide-static
```

```tsx
import { Svg, Path, Rect } from "@react-pdf/renderer";

// Converted from lucide-static/icons/mail.svg
const MailIcon = ({ size = 12, color = "#888" }) => (
  <Svg width={size} height={size} viewBox="0 0 24 24">
    <Path d="m22 7-8.991 5.727a2 2 0 0 1-2.009 0L2 7" stroke={color} strokeWidth={2} fill="none" />
    <Rect x="2" y="4" width="20" height="16" rx="2" stroke={color} strokeWidth={2} fill="none" />
  </Svg>
);
```

## Links and Navigation

```tsx
<Link src="https://example.com"><Text>Visit website</Text></Link>

<View id="section-1"><Text>Target</Text></View>
<Link src="#section-1"><Text>Jump to Section 1</Text></Link>
```

## Dynamic Content and Page Numbers

```tsx
<Text render={({ pageNumber, totalPages }) => `Page ${pageNumber} of ${totalPages}`} />
```

## Fixed Headers/Footers

```tsx
<Page size="A4">
  <View fixed style={{ position: "absolute", top: 20, left: 30, right: 30 }}>
    <Text>Header</Text>
  </View>
  <View style={{ marginTop: 60, marginBottom: 60 }}>
    <Text>Content</Text>
  </View>
  <Text
    fixed
    style={{ position: "absolute", bottom: 20, left: 30, right: 30, textAlign: "center" }}
    render={({ pageNumber, totalPages }) => `Page ${pageNumber} of ${totalPages}`}
  />
</Page>
```

## Page Breaks and Wrapping

```tsx
<View break />                              // Force page break
<View wrap={false}><Text>Keep together</Text></View>  // Prevent breaking inside
<Text orphans={2} widows={2}
Files: 4
Size: 90.4 KB
Complexity: 54/100
Category: Web Dev

Related in Web Dev