PDFPipe

React to PDF

Export a React component to a real PDF

Render the component you already built to HTML, send it to a print engine, and stream back a PDF with selectable text, the right fonts, and page breaks that land where they should. No canvas screenshots, no rewriting your UI, no Chrome in your bundle.

Why the usual approaches let you down

html2canvas + jsPDF

Screenshots the DOM into a bitmap. The text is not selectable or searchable, it pixelates on zoom, and anything lazy-loaded or off-screen never makes it in.

@react-pdf/renderer

Real PDF, but you rebuild the whole document in its own View and Text primitives. Your CSS, your design system, and your Tailwind classes do not transfer.

Puppeteer in your app

Bundling headless Chrome works on your laptop and breaks in production: it does not fit most serverless functions, cold starts add seconds, and it leaks memory under load.

The whole integration

Render your component to an HTML string on the server with renderToStaticMarkup, post it, and return the PDF. The same JSX you ship to the screen becomes the document.

TypeScript
// Render the component, post the HTML, stream a PDF back.
import { renderToStaticMarkup } from "react-dom/server";
import { Receipt } from "@/components/Receipt";

export async function POST(req: Request) {
  const { data } = await req.json();
  const html = "<!doctype html>" + renderToStaticMarkup(<Receipt {...data} />);

  const res = await fetch("https://api.pdfpipe.xyz/v1/pdf", {
    method: "POST",
    headers: {
      Authorization: `Bearer ${process.env.PDFPIPE_API_KEY}`,
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ html, options: { format: "A4" } }),
  });

  return new Response(res.body, {
    headers: { "Content-Type": "application/pdf" },
  });
}

Want the full walkthrough with the component, the button, and the plain-React (no Next.js) version? Read the React to PDF guide.

What you get

  • Real vector text that is selectable, searchable, and crisp at any zoom.
  • Web fonts and images loaded before the page is drawn, so it matches your UI.
  • Clean multi-page output that respects break-inside: avoid.
  • Your existing CSS and component code, unchanged.
  • Isolation against malicious HTML when template data comes from your users.

500 free documents a month, flat pricing after that, and a live playground you can try without signing up.

Get your API key →