Skip to main content
Skip pdfn Cloud and run the full pipeline yourself. You control the browser, the infrastructure, and the output.
Want managed PDF generation? Use client.generate() with pdfn Cloud — no infra or browser management needed.

How it works

React Component → render() → HTML → Puppeteer/Playwright → PDF
  1. render() converts your React template to self-contained HTML
  2. You pass that HTML to Puppeteer or Playwright to generate a PDF

Setup

npm install @pdfn/react puppeteer
import { pdfn } from '@pdfn/react';
import puppeteer from 'puppeteer';
import fs from 'node:fs';
import Invoice from './pdfn-templates/invoice';

async function generatePdf() {
  const client = pdfn();

  // 1. Render React to HTML
  const { data, error } = await client.render({ react: <Invoice /> });

  if (error) {
    console.error(error.message);
    return;
  }

  // 2. Convert HTML to PDF
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  await page.setContent(data.html, { waitUntil: 'networkidle0' });
  await page.waitForFunction(() => window.PDFN?.ready === true);

  const pdf = await page.pdf({
    preferCSSPageSize: true,
    printBackground: true,
  });

  await browser.close();

  fs.writeFileSync('invoice.pdf', pdf);
}

generatePdf();
Add @pdfn/tailwind if your templates use Tailwind CSS. See Styling.

Required PDF options

Always use these two options when calling page.pdf():
await page.pdf({
  preferCSSPageSize: true,  // Respect page size from template
  printBackground: true,    // Include background colors
});
And always wait for pdfn to finish pagination before generating:
await page.waitForFunction(() => window.PDFN?.ready === true);
This ensures fonts are loaded and page breaks are calculated.

Comparison

pdfn CloudSelf-Hosted
SetupManaged — no infra or browser setupYou manage infra and Chromium
ScalingAuto-scalesYou handle scaling
CompliancePDF/A-1b, PDF/A-2b, PDF/A-3bNot available
CostUsage-based pricingYour infrastructure costs

Next steps