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

To print a React component with Puppeteer, first turn it into HTML the browser can render, then call Puppeteer’s page.pdf() on that page. Puppeteer does not accept a React component object directly. For a simple invoice or report, render the component to an HTML string with React’s server renderer and load it with page.setContent(). For a component that depends on your app’s styles, assets, or data loading, open a dedicated route with page.goto() and print that page instead.

Choose how Puppeteer will load the component

The right setup depends on what the component needs to look correct. In both cases, React supplies browser-renderable HTML and Puppeteer prints the browser page as a PDF.

Use server-rendered HTML for a self-contained report

React’s renderToString() can turn a React tree into an HTML string. This is useful for documents such as an invoice whose content and styles are available to the server. The output is initial, non-interactive HTML: it does not hydrate the component or wait for data that has not already been fetched.

When using page.setContent(), make sure required CSS, fonts, images, and other assets are reachable from the generated document. Relative asset paths may resolve differently than they do on your app route; use suitable absolute URLs or inline the required styles and assets.

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

Use a dedicated route when the app provides the document

If the component relies on your built application bundle, shared stylesheets, client-side data loading, or app-specific rendering behavior, expose a route that renders the intended document and navigate Puppeteer to it. This follows the browser-page workflow in Puppeteer’s PDF guide: navigate to a URL, call page.pdf(), and close the browser.

A route does not automatically mean the component is ready to print as soon as navigation finishes. Your application may need extra time or a specific readiness signal for data and images. Wait for something meaningful to the page rather than assuming that font readiness also means every other resource has loaded.

Generate a PDF from server-rendered React HTML

This Node.js ES-module example renders an invoice component, loads its HTML in Chromium, and writes invoice.pdf. It assumes Invoice and invoiceData are available in the same module, and that the component’s required styles and assets are included or otherwise reachable.

import React from 'react';
import { renderToString } from 'react-dom/server';
import puppeteer from 'puppeteer';
import { Invoice } from './Invoice.js';

const invoiceData = {
  number: 'INV-1042',
  customer: 'Example Customer',
  total: '$240.00',
};

const body = renderToString(
  React.createElement(Invoice, { data: invoiceData })
);

const html = `<!doctype html>
<html>
  <head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <style>
      @page { size: A4; margin: 18mm; }
      @media print {
        body { margin: 0; }
        .page-break { break-before: page; }
      }
      body { font-family: Arial, sans-serif; color: #222; }
      h1 { color: #17324d; }
      @media print {
        * { -webkit-print-color-adjust: exact; print-color-adjust: exact; }
      }
    </style>
  </head>
  <body>${body}</body>
</html>`;

const browser = await puppeteer.launch();
try {
  const page = await browser.newPage();
  await page.setContent(html);
  await page.pdf({
    path: 'invoice.pdf',
    format: 'A4',
    printBackground: true,
  });
} finally {
  await browser.close();
}

The code shows the core API pattern; it was not runtime-tested. Install React, React DOM, and Puppeteer in your project, and adapt the import and component data to your app. If the invoice needs application styles that are not in the HTML string, use a route instead or ensure those styles are loaded by the document.

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.

Print a route from your React app

For a real app page, replace the setContent() step with navigation to the route. Keep the same PDF options and cleanup pattern:

import puppeteer from 'puppeteer';

const browser = await puppeteer.launch();
try {
  const page = await browser.newPage();
  await page.goto('https://your-app.example.com/print/invoice/INV-1042', {
    waitUntil: 'networkidle0',
  });
  await page.pdf({
    path: 'invoice.pdf',
    format: 'A4',
    printBackground: true,
  });
} finally {
  await browser.close();
}

Use your actual deployed or locally accessible route. The networkidle0 navigation condition can be appropriate for pages that settle after network activity, but some apps keep connections open or load data later. In that case, wait for an app-specific selector that appears when the printable content is ready, or use a deliberate delay only when you cannot expose a better readiness signal. Do not treat a successful navigation as proof that asynchronous content is complete.

Set print media, page size, colors, and margins deliberately

Puppeteer’s PDF generation uses the browser’s print CSS media type by default. That means print styles, rather than your normal screen styles, determine layout unless you explicitly change the media type.

  • Use print CSS for documents. Define page breaks, hide controls, and adjust spacing in @media print rules.
  • Use screen styles only when needed. Call await page.emulateMediaType('screen') before page.pdf() if the PDF should follow screen styling. This changes the media type used for the page.
  • Choose a page geometry. Set a named format, such as 'A4' or 'Letter', or supply width and height. When format is set, it takes precedence over width and height.
  • Decide which page-size rule wins. Set preferCSSPageSize: true when a CSS @page size should take precedence over the PDF options’ paper size.
  • Specify orientation and margins. Use landscape: true for landscape output and set margin to control the PDF’s printable area. Keep CSS @page margins in mind so you do not accidentally apply conflicting geometry.
  • Enable backgrounds when the design needs them. printBackground defaults to false. Set it to true for colored panels, background graphics, or other design elements that should print.

Browsers may adjust colors for print. If preserving the CSS colors matters, use -webkit-print-color-adjust: exact in print styles and inspect the resulting PDF. Exact color adjustment is a rendering instruction, not a guarantee that every printer or PDF viewer will display colors identically.

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.

Wait for the right content before printing

Puppeteer waits for fonts by default during PDF generation; the PDF options reference also documents waitForFonts: true, which waits for document.fonts.ready. Font readiness is only one part of document readiness. It does not establish that your data requests, images, charts, or other app-specific work have finished.

For a route, wait for a selector that marks the document as ready before creating the PDF:

await page.goto('https://your-app.example.com/print/invoice/INV-1042');
await page.waitForSelector('[data-print-ready="true"]');
await page.pdf({ path: 'invoice.pdf', format: 'A4', printBackground: true });

Have the React route add that attribute only after the data needed for printing is ready. For setContent(), wait for any required resource or application work after setting the content. Then inspect the PDF itself: assets can still be missing because a URL is wrong, inaccessible, or blocked.

Common problems and fixes

  • The PDF is empty or missing the component. Puppeteer prints the page, not a React component object. Render the component to HTML or navigate to a route that renders it, then confirm that the browser page contains the expected content before printing.
  • The PDF has no app styling. HTML inserted with setContent() does not automatically include your app’s built stylesheets. Link or inline the necessary styles, make asset URLs resolvable, or print a route that loads the app bundle.
  • Colors or background panels disappear. PDF backgrounds are off by default. Set printBackground: true; use -webkit-print-color-adjust: exact in print CSS when preserving color is important.
  • The layout differs from the browser view. PDF generation uses print media by default. Add print-specific CSS or call page.emulateMediaType('screen') before printing if screen styles are the intended result.
  • Content is clipped or split awkwardly. Review the chosen format, margins, component width, and print rules. Add appropriate page-break behavior for sections, and check the actual output for content that crosses page boundaries.
  • Images or asynchronous data are missing. Font readiness alone does not mean every image or request is complete. Wait for the app’s data-ready signal, confirm resource URLs work from the browser process, and inspect the page before calling page.pdf().
  • The process hangs or leaves Chromium running. Put browser.close() in a finally block so cleanup runs after either success or an error. Investigate navigation and application readiness conditions if a wait never resolves.
  • A production host cannot launch Chromium. Puppeteer requires a browser process that the runtime can launch. Check that the deployment environment supports the browser and its runtime dependencies; configuration differs by host, and no single hosting-provider setup is implied here.

Performance, reliability, and output checks

PDF creation includes launching or reusing a browser, loading the page, waiting for its content, and generating the document. The exact time depends on your application and runtime; no performance figure is established here. For a service that generates many PDFs, consider a managed browser lifecycle rather than launching a new browser for every document, while ensuring pages and browser processes are closed reliably.

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

Keep each print route focused: fetch only the data and assets the document needs, and expose a clear ready state. Test representative cases such as long invoices, missing optional fields, large tables, and content that spans multiple pages. Check page breaks, clipping, font substitution, image loading, links, and colors in the generated PDF rather than assuming the HTML preview guarantees print fidelity.

The PDF options reference also lists tagged and outline as experimental features. Do not rely on them for accessibility or outline behavior without validating the output for your installed Puppeteer version and document.

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 you need a screenshot of a rendered React page rather than a PDF generated from a component, ScreenshotNeo can capture the page through one GET request. It is a website screenshot API and MCP server, not a replacement for the React rendering step: give it a URL that already renders the page you want captured. For its PDF options and request details, see the ScreenshotNeo documentation.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://your-app.example.com/print/invoice/INV-1042 -o shot.webp

Cookie banners, newsletter popups, and chat widgets are removed before capture; those cleanup steps can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers identify the page verdict and billing status. An MCP server lets AI agents using Claude, Cursor, or other MCP clients take screenshots. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. If the job is specifically to produce a PDF from a React component, use the Puppeteer workflow above or consult the API documentation for the PDF request options.

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

Sign up for ScreenshotNeo’s free plan: 1,000 screenshots a month, no card required.

Best Value
The SQL Programming Language: .
  • Used Book in Good Condition

Frequently Asked Questions

Does Puppeteer render a React component directly?

No. It prints a browser page, so React must first provide HTML through a rendered route or server-rendered markup.

Does `renderToString()` make the component interactive?

No. It returns initial HTML; it does not hydrate the component or load data that has not already been obtained.

Can I use ScreenshotNeo to print a React component to PDF?

ScreenshotNeo captures a URL that already renders the page. For PDF-specific request options, consult its documentation; Puppeteer’s `page.pdf()` is the direct workflow described here.

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

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.