§ React to PDF
React to PDF: Convert a React Component or Page to a Real PDF
Turn a React component, a rendered page, or raw HTML into a pixel perfect PDF with one API call. Managed Chromium renders your real markup, so text stays selectable and your Tailwind and web fonts survive, no html2canvas screenshot, no browser to run yourself. Try it on any URL below.
- Early access, launching soon
- No card required
- Your HTML stays yours
§ Live demo
Runs in your browser. Nothing is uploaded.
Your HTML
Live preview
Your PDF is downloading. Want this as one API call, with the page archived too?
§ Short answer
The reliable way to convert React to PDF for production is to render your real React output in a browser on the server, not to screenshot the DOM in the client. Client-side tools like react-to-pdf and html2canvas take a raster snapshot: the text is not selectable, it pixelates when zoomed, and Tailwind v4 oklch() colors break the capture outright. Sitepdf renders the same HTML your React app produces in managed Chromium and returns a true, searchable vector PDF, plus an optional timestamped archive of exactly what was rendered.
Last updated July 2026. Written and fact checked by the Sitepdf team.
§ 00
Three ways to get a PDF out of React, compared
React has no built in PDF export, so every team picks one of these three approaches. They differ most in whether the PDF contains real text and whether your app CSS actually applies.
| Approach | How it works | Output | Modern CSS and Tailwind v4 | Best for |
|---|---|---|---|---|
| @react-pdf/renderer | You rewrite the layout as its own JSX primitives (View, Text) | True vector PDF | No: its own layout engine, your app CSS does not apply | Designing a PDF from scratch, not reusing a page |
| react-to-pdf, html2canvas + jsPDF client side |
Snapshots a DOM node in the browser and drops the image into a PDF | Raster image, text not selectable, pixelates on zoom | Breaks: oklch() colors throw, gradients and shadows drift | A quick client export of one simple, static screen |
| Server side Chromium API Sitepdf |
Renders your real page or HTML in a managed browser | True searchable vector PDF, print accurate | Full support, it is a real current browser | Production documents, identical output for every user, a dated record |
The honest read: @react-pdf/renderer is excellent when the PDF is a distinct design you build in JSX, and it is genuinely the right tool for that. If instead you want the PDF to look like the page your users already see, a real browser has to do the rendering, which is why the client screenshot route keeps disappointing teams once fonts, charts and Tailwind enter the picture.
§ 01
Why the client-side screenshot route keeps letting teams down
The most common first attempt is react-to-pdf or a hand rolled html2canvas plus jsPDF combination. It is appealing because it runs entirely in the browser and needs no backend. It also quietly produces a worse document than people expect. Under the hood these libraries paint the component onto a canvas and embed that canvas as an image, so the PDF is a picture of your UI. The text inside cannot be selected, copied or searched, it turns fuzzy the moment someone zooms in, and it does not reflow, so a tall report becomes one enormous image awkwardly sliced across pages.
Then there is the CSS problem that arrived with Tailwind v4. Tailwind now emits colors in the oklch() function, and html2canvas cannot parse it, so the capture fails with "Attempting to parse an unsupported color function oklch". You can patch it by overriding every color at render time, but that is a maintenance tax you pay forever. A real browser has none of these limits because it is the same engine that drew the page in the first place.
§ 02
The server-side path: render your real React output, keep real text
The fix is to move the rendering off the client and into a real browser. You have two clean ways to feed Sitepdf. If the document is a live route in your app, an invoice page, an order confirmation, a dashboard export, point the API at that URL and it loads the page in managed Chromium exactly as a visitor would, runs your JavaScript, waits for your charts, and returns the PDF. If you would rather not expose a route, render the component to an HTML string on the server with renderToStaticMarkup from react-dom/server and post that HTML instead.
import { renderToStaticMarkup } from "react-dom/server";
import Invoice from "./Invoice";
const html = renderToStaticMarkup(<Invoice data={invoice} />);
const res = await fetch("https://api.sitepdf.com/v1/render", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.SITEPDF_KEY}` },
body: new URLSearchParams({ html, format: "Letter", archive: "true" }),
});
const { pdf_url } = await res.json();Either way the browser does the layout, so your Tailwind classes, CSS grid, web fonts and background colors all render the way they do on screen, and the resulting text is real, selectable and searchable. Our HTML to PDF in Node.js guide covers the same call from an Express or Next.js API route, and the PDF generator API page has the full parameter list.
§ 03
When @react-pdf/renderer is the better choice
We are not going to pretend the API is always the answer. If your PDF is a bespoke document that looks nothing like any page in your app, a shipping label, a certificate, a fixed format statement, then @react-pdf/renderer is a genuinely good fit and it costs nothing. You describe the document with its own <View> and <Text> primitives, and because it never touches a browser it is fast and has no infrastructure. The catch is exactly that separation: it ignores your existing CSS, so you are rebuilding the layout in a second styling system, and complex responsive designs are painful to express in its subset.
So the rule is simple. Reusing a page or a template your users already see, and you want it to match? Render it in a real browser. Building a brand new document layout from scratch in code, with no HTML to reuse? @react-pdf/renderer earns its place. The screenshot libraries are the one option that rarely wins on a document that matters, because they trade away real text for convenience.
§ 04
Keep a dated copy of what you generated
There is one thing no React library gives you, on the client or the server: a record. When you generate an invoice, a receipt or a signed quote, the file goes to the customer and nothing verifiable stays with you. Add archive=true to the render call and Sitepdf also stores a timestamped, immutable snapshot of exactly what it rendered, retrievable by id later. For finance, legal and compliance work that provenance is often the reason to render server side in the first place. The website archiving page explains how the record works, the Vue to PDF and Angular to PDF pages walk the same trade offs for the other big component frameworks, and if you are weighing running your own headless Chrome instead, the Puppeteer alternative page runs that trade off honestly. Renders are transient by default; leave archiving off and we return the PDF and store nothing.
curl https://api.sitepdf.com/v1/render \
-H "Authorization: Bearer $SITEPDF_KEY" \
-F url=https://app.example.com/invoices/8842 \
-F format=Letter \
-F wait_for="#invoice-total" \
-F archive=true
{
"pdf_url": "https://api.sitepdf.com/v1/documents/doc_9r2la.pdf",
"pages": 2,
"rendered_in_ms": 1740,
"archive": {
"id": "arc_k70bd",
"captured_at": "2026-07-19T18:04:12Z",
"retrieve_url": "https://api.sitepdf.com/v1/archives/arc_k70bd"
}
}
The API is in early access; this is the documented call shape it opens with. Full request and response walkthrough.
§ 05
Questions about this job
How do I convert a React component to PDF?
Why is my react-to-pdf output blurry or not selectable?
Does html2canvas work with Tailwind v4?
Should I use @react-pdf/renderer or a rendering API?
Can I generate the PDF from a Next.js API route?
§ Index
More PDF and archiving tools
- Convert HTML to PDF
- Webpage to PDF
- Save webpage as PDF
- URL to PDF API
- Website archiving
- Screenshot API
- Laravel HTML to PDF
- Vue to PDF
- Next.js PDF generator
- Angular to PDF
- Markdown to PDF API
- Django HTML to PDF
- Blazor HTML to PDF
- Spring Boot HTML to PDF
- Airtable to PDF
- Rails HTML to PDF
- PDF generator API
- Document generation API
- Bulk HTML to PDF
- Wayback Machine alternative
- Best HTML to PDF API
- DocRaptor alternative
- Puppeteer alternative
- Wkhtmltopdf alternative
- PDFShift alternative
- Urlbox alternative
- PDFCrowd alternative
- Api2Pdf alternative
- Browserless alternative
- APITemplate alternative
- CraftMyPDF alternative
- PDFMonkey alternative
- dompdf alternative
- Gotenberg alternative
- GrabzIt alternative
- How it works
- Features
- Pricing
§ Early access
Get on the early-access list
The API opens to the list first, in order. Early access locks the planned launch rates for 12 months. No card required, launching soon.