Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The best method depends on what you are exporting. For a new report, invoice, or certificate built from structured data, use @react-pdf/renderer and compose a PDF-specific component tree. If you need to export an element that is already rendered in the browser, use a DOM-capture workflow such as html2canvas with jsPDF, while accepting that unsupported CSS and cross-origin assets can affect the result.

This guide shows a current React PDF workflow, browser and server output choices, a DOM-export alternative, troubleshooting, and a no-browser option for turning a public page into a PDF.

Choose the right PDF strategy first

Requirement Recommended approach Why
Generate a document from data @react-pdf/renderer You control a PDF document tree, page size, typography, and layout independently of your web CSS.
Show or download that generated document in a React browser app @react-pdf/renderer with PDFViewer or its browser data APIs The renderer produces PDF output directly in the browser.
Create a file on a server @react-pdf/renderer server file or stream API PDF generation happens on the server and can be saved or returned as application/pdf.
Export an existing on-screen element html2canvas plus jsPDF The workflow starts with a DOM element, but it only reproduces CSS and browser resources the capture library supports.

Do not treat these as interchangeable. A report component designed for react-pdf is not your normal HTML component, and a DOM capture is not a literal screenshot of every browser-rendered feature.

Generate a PDF document with @react-pdf/renderer

Install the current package

Install the package in the React project that will render the document:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
#1 Best Overall
Epson EcoTank ET-2800 Wireless Color All-in-One Supertank Printer - Black
  • INNOVATIVE CARTRIDGE-FREE PRINTING — No more dealing with lots of tiny ink cartridges; With this wireless document and photo printer each ink bottle set is equivalent to about 90 individual cartridges²
  • LESS FREQUENT INK REPLACEMENT — Replacement ink bottles don't have to be changed nearly as often as ink cartridges¹; When you choose this combination printer, scanner and copier you can print up to 4,500 pages black/7,500 color³
  • COLOR PRINTING — Up to 2 years of ink in the box4 (and with every replacement ink set) for fewer out-of-ink frustrations
  • ZERO CARTRIDGE WASTE — By using an Epson EcoTank printer you can help reduce the amount of cartridge waste ending up in landfills
  • HOME PRINTER DESIGNED FOR RELIABILITY — The Epson EcoTank ET-2800 All-in-One Supertank Color Printer creates vivid, detailed prints and documents thanks to Micro Piezo Heat-Free Technology; Fire off 10 ISO pages per minute1 to easily finish large jobs
npm install @react-pdf/renderer --save

The package’s current v4 documentation uses React components for PDF layout. Package versions and APIs can change, so check the version installed in your lockfile when adapting this example.

Create the document component

Document is the root of the react-pdf tree. Its direct children should be Page elements. Put text in Text, grouping and layout in View, and styles in StyleSheet. The document also accepts metadata such as title and author.

import { Document, Page, Text, View, StyleSheet } from '@react-pdf/renderer';

const styles = StyleSheet.create({
  page: {
    padding: 36,
    fontSize: 12,
  },
  section: {
    marginBottom: 12,
  },
  heading: {
    fontSize: 18,
    marginBottom: 8,
  },
});

export function ReportPdf({ title, body, author = 'Example application' }) {
  return (
    <Document title={title} author={author}>
      <Page size="A4" style={styles.page}>
        <View style={styles.section}>
          <Text style={styles.heading}>{title}</Text>
          <Text>{body}</Text>
        </View>
      </Page>
    </Document>
  );
}

This is a PDF layout tree, not ordinary browser markup. Use the renderer’s supported style properties and Flexbox-like layout model rather than assuming every web CSS property is available.

Display the PDF in the browser

Wrap the document component in PDFViewer when the user should see an embedded viewer:

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
import { PDFViewer } from '@react-pdf/renderer';
import { ReportPdf } from './ReportPdf';

export default function ReportPreview({ title, body }) {
  return (
    <PDFViewer style={{ width: '100%', height: '80vh' }}>
      <ReportPdf title={title} body={body} />
    </PDFViewer>
  );
}

Keep the viewer mounted only where a browser PDF preview is appropriate. For a download button or a generated object URL, use the browser-side PDF data methods documented for the exact package version you installed; older v2 manual pages are marked unmaintained and should not be copied into a v4 implementation without verification.

Rank #2
Sale
Epson EcoTank Photo ET-8550 Wireless Wide-Format All-in-One Tank Printer
  • CARTRIDGE-FREE PRINTING — Print lab-quality photos, graphics and creative projects; Get vibrant colors and sharp text with Epson's high-accuracy printhead and Claria ET Premium 6-color inks
  • INK BOTTLES — Save on photos1 and creative projects with affordable in-house printing; All-in-one printer allows you to print 4" x 6" photos for about 4 cents each vs. 40 cents with traditional ink cartridges1
  • LESS FREQUENT INK REPLACEMENT — Replacement ink bottles don't have to be changed nearly as often as ink cartridges¹; Printer, scanner and copier lets you print up to 6,200 color pages³
  • PRINT FOR LONGER — Up to 2 years of ink in the box² (and with every replacement ink set) for fewer out-of-ink frustrations with this wireless printer
  • ZERO CARTRIDGE WASTE — Epson EcoTank printer helps reduce the amount of cartridge waste ending up in landfills; Cartridge-free printer uses high-yield ink bottles; Each replacement ink bottle set is equivalent to about 100 individual ink cartridges⁴

Render a file or HTTP response on the server

For server-side generation, pass the same document component to the renderer’s file API and a destination path. In an HTTP handler, use its stream API and send the stream with an application/pdf response header. The choice is operational:

  • Use a file API for a scheduled export, temporary file, or object-storage upload.
  • Use a stream for an immediate download or API response without first writing a permanent file.
  • Keep browser-only objects out of the document component when it must also render on a server.

Design the document as a pure function of its props. Fetch data before rendering, validate required fields, and pass serializable values such as strings, numbers, dates converted to display strings, and arrays of line items.

Build practical documents: pages, data, and assets

Use explicit page boundaries when necessary

Long content can flow across pages, but business documents often need deliberate sections. Use additional Page elements for a cover, summary, or appendix. Keep repeated headers and footers in components that are included consistently on each page, and test documents with short and unusually long values.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Keep web and PDF components separate

A responsive dashboard component may rely on browser CSS, event handlers, and interactive controls that have no meaning in a PDF. Create a PDF view model and a PDF component instead of attempting to serialize the entire DOM. This separation also makes server rendering possible.

Plan for fonts and images

Use assets that the runtime can read reliably and verify font registration and image loading in the environment where the PDF is produced. A document that looks correct in a local browser can fail in a server process if a relative path, protected URL, or browser-only API is used.

Rank #3
HP Smart Tank 5000 Wireless All-in-One Ink Tank Printer, Scanner, Copier with 2 Years of Ink Included, Best-for-Home, Cartridge-Free, Refillable and AI-Enabled. (5D1B6A)
  • SET IT UP ONCE AND PRINT WITH CONFIDENCE. No complicated maintenance. Just easy, reliable printing you can count on.
  • INK FOR YEARS. NOT MONTHS. Up to 2 years of ink included. Get thousands of pages of cartridge-free printing. More pages, less hassle
  • KEEPS PRINTING WELL AFTER COMPETITORS HAVE QUIT. No complex maintenance. Sharper text, richer colors.[2] Only with HP Smart Tank
  • PREMIUM SUPPORT - Strong technical expertise to solve issues faster
  • THE LAST PRINTER YOU'LL EVER NEED. Enjoy years of refillable, cartridge-free printing.

Export an existing React DOM element

If the requirement is “export this card exactly as it appears on screen,” a DOM-capture workflow is more direct:

npm install html2canvas jspdf
import html2canvas from 'html2canvas';
import { jsPDF } from 'jspdf';

export async function downloadElementAsPdf(element) {
  const canvas = await html2canvas(element, {
    backgroundColor: '#ffffff',
    useCORS: true,
    scale: window.devicePixelRatio || 1,
  });

  const image = canvas.toDataURL('image PNG');
  const pdf = new jsPDF({
    orientation: canvas.width > canvas.height ? 'landscape' : 'portrait',
    unit: 'pt',
    format: 'a4',
  });

  const pageWidth = pdf.internal.pageSize.getWidth();
  const pageHeight = pdf.internal.pageSize.getHeight();
  const ratio = Math.min(pageWidth / canvas.width, pageHeight / canvas.height);
  const width = canvas.width * ratio;
  const height = canvas.height * ratio;

  pdf.addImage(image, 'PNG', (pageWidth - width) / 2, 0, width, height);
  pdf.save('export.pdf');
}

Call the function with a reference to the element:

const node = document.querySelector('#invoice');
if (node) {
  await downloadElementAsPdf(node);
}

Use the correct MIME string in production: canvas.toDataURL('image/png'). The example’s layout scales one captured canvas to one PDF page. For tall content, split the canvas into page-height slices or use a pagination strategy; otherwise the lower part may be clipped or reduced until it is hard to read.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Know what DOM capture cannot promise

html2canvas does not actually take a screenshot of the page; it builds a representation based on the properties it reads from the DOM. Unsupported CSS, pseudo-elements, filters, complex positioning, videos, and browser-specific rendering can therefore differ from the live page. Cross-origin images and other resources can taint the canvas unless they are same-origin or served with permissive CORS headers (or handled through an allowed proxy). Test real fonts, image URLs, page breaks, and target browsers before making a fidelity guarantee.

Browser versus server generation

Choose browser generation when

  • The user needs an immediate preview or download from data already in the page.
  • The document does not contain secrets that should leave your server.
  • You can tolerate work occurring on the user’s device.

Choose server generation when

  • You need a consistent output for emailed invoices, archival, or automated jobs.
  • Data access belongs on the server.
  • You want to stream a PDF from an API with an application/pdf header.

Whichever runtime you select, keep the PDF component deterministic. Log input validation failures separately from rendering failures, and return a useful HTTP status instead of an HTML error page with a PDF content type.

Common errors and fixes

Symptom Likely cause Fix
Blank or incomplete PDF Data or images were not ready when rendering began. Await data loading, pass resolved props, and verify every asset URL in the target runtime.
“Element type is invalid” or missing PDF primitives Import mismatch or mixing browser HTML components with react-pdf components. Import Document, Page, Text, and View from @react-pdf/renderer; keep DOM elements outside the PDF tree.
CSS looks different react-pdf has its own style model, or html2canvas does not support the CSS used. For authored documents, rewrite styles using supported primitives. For DOM capture, simplify unsupported styles and test the exact browser.
Canvas is tainted or toDataURL fails A cross-origin image or resource lacks appropriate CORS handling. Serve assets from the same origin, configure CORS correctly, or use a permitted proxy; do not disable browser security.
Text is tiny on multipage export A tall canvas was shrunk to fit one page. Slice the canvas into page-sized sections and add each section to the PDF at readable dimensions.
Server rendering crashes with a browser API error The document imports or calls window, document, or other browser-only code. Separate browser preview code from the shared PDF component and keep server inputs serializable.
Viewer does not fill its area The PDFViewer element has no usable width or height. Set explicit dimensions through its style or a sized parent container.

Performance, reliability, and cost considerations

  • Large images increase memory use in both browser and server generation. Resize images to their intended print dimensions before embedding them.
  • High device-pixel-ratio DOM captures produce sharper output but consume more memory. Choose a scale deliberately and test mobile devices.
  • Long reports should be tested with the maximum realistic row count, long translated strings, missing optional fields, and slow image requests.
  • For repeatable exports, prefer react-pdf’s document model over capturing a changing UI. It avoids depending on scroll position, animations, overlays, and incidental page state.
  • Do not report a successful download merely because a request returned status 200. Confirm that the response body is a PDF and that rendering completed before exposing it to the user.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

If the input is a public web page rather than structured application data, ScreenshotNeo can return a screenshot or PDF from one API request. It accepts cookie and consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each cleanup step can be disabled. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the page and billing result in X-Page-Verdict and X-Billed headers. An MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients.

For the API syntax and all options, see the ScreenshotNeo documentation. The same endpoint can produce a PDF; the example below follows the documented request shape:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #4
NDYIN Portable Printers Wireless for Travel, N80 Bluetooth Thermal Printer
  • Wireless Bluetooth Printer: Portable thermal printer compatible with iPhone, Android phones, iPad and tablet computers via Bluetooth. For smartphones, please download the "Nada Print" App. You can also connect to laptops and computers for printing using a USB-C cable. (Note: Laptops and computers can only be connected via USB and require the installation of a driver first. Bluetooth connection is not supported.)
  • No-ink printing: Only supports US Letter and A4 size thermal paper.(Doesn't support regular paper) The no-ink portable thermal printer uses direct thermal technology, requiring no ink, toner or ribbons, making it environmentally friendly, cost-effective and time-saving. The thermal printer package comes with a roll of US Letter thermal printing paper. Note: When installing the paper, remember to switch the paper size switch on APP
  • Clear Print: NDYIN N80 portable thermal printer adopts high-definition printing technology, with a 203DPI resolution to provide you with clear printing results. This mobile printer is compatible with roll paper, folded paper and tattoo transfer paper, supporting printing from your mobile phone PDF, Word, pictures and web pages anytime and anywhere. It is recommended to use our NDYIN thermal paper to achieve good printing quality
  • Portable wireless printer for travel: The thermal printer is equipped with a built-in 1500mAh rechargeable battery, which can print 160 sheets of 8.5" x 11" thermal paper after being fully charged. It weighs only 1.5 pounds and is compact in size. This ink-free portable printer can be easily carried in a backpack or briefcase! It is perfect for business travel, cars, small offices, construction sites, schools and homes. You can print documents, contracts, invoices and boarding passes anytime and anywhere
  • The N80 thermal printer has a wide range of uses. The package includes the N80 printer, a roll of US Letter paper(7m/roll), a user manual, a guide card, a type-C soft cable and a type C adapter. Note: The charging adapter is not included. Special thermal paper is required for use; ordinary paper cannot be used. This ink-free portable thermal printer is suitable for various scenarios such as home, school, travel, office, and outdoor, meeting the printing needs of different groups of people. This tattoo template printer is also compatible with tattoo transfer paper, making it an ideal choice for tattoo art
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

Replace the URL with the page you need and choose the PDF output option described in the documentation. The service also supports full-page capture with lazy images loaded, CSS-selector element capture, dark mode, device presets, custom viewport and retina scale, paper size, margins, landscape mode, page ranges, custom CSS and JavaScript, clicks, selector or network-idle waits, request and resource blocking, headers, cookies, user agents, authorization, timezone, geolocation, transparent backgrounds, resizing, configurable-TTL caching, signed links, asynchronous jobs with signed webhooks, bulk capture for up to 100 URLs per call, usage reporting, and an OpenAPI specification. Parameter names used by other screenshot APIs are accepted to ease migration.

The Free plan includes 1,000 shots each month without a card. Paid plans start at $5 for 3,000 shots; every feature is available on every plan, and yearly billing provides two months free. Create a free ScreenshotNeo account to try it.

Which method should you ship?

  • Use @react-pdf/renderer for invoices, reports, certificates, and any PDF whose layout is part of your application.
  • Use html2canvas and jsPDF only when exporting an existing DOM element is more important than perfect CSS fidelity.
  • Use server rendering for controlled, repeatable files and browser rendering for interactive previews and user-initiated downloads.
  • Use ScreenshotNeo when the source is an external page and you want a managed capture pipeline rather than installing and operating a browser.

Frequently Asked Questions

Can I use normal HTML tags inside a react-pdf document?

No. Build the PDF tree with react-pdf primitives such as Document, Page, View, and Text. Keep ordinary HTML in the surrounding React interface.

Does html2canvas work in Node.js?

No. It depends on browser APIs, so use it in a browser or choose a server-capable PDF renderer.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Why does my captured PDF differ from the web page?

DOM capture reconstructs the page from readable DOM and CSS properties; unsupported styles, fonts, animations, and cross-origin resources can change the result.

Should I use an old react-pdf v2 tutorial?

Not without checking it against the installed version. Older advanced documentation is explicitly unmaintained; follow the current v4 API for new work.

Quick Recap

Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.