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

Use Puppeteer’s asynchronous Page.pdf() method to render each HTML document, then await the jobs together with Promise.all() or a concurrency-limited worker pool. This produces one PDF per HTML input. If you need a single combined PDF, add a PDF merge step or combine the content into one HTML document before rendering.

What “asynchronously” means for Puppeteer PDF generation

Puppeteer’s Page.pdf() returns a promise that resolves to PDF bytes. You can await several independent render jobs without writing them as a serial sequence. That does not guarantee that parallel rendering will be faster: each open page uses browser and host resources, so throughput depends on the documents and the machine running Chromium.

There is an important output distinction. Page.pdf() renders a page; it does not automatically join PDFs made from several HTML inputs. With separate inputs, the straightforward result is a collection of PDF files. A combined deliverable requires another step: merge those files with a PDF library, or first build one HTML document containing the material in the required order and render that document once.

Render multiple HTML strings into separate PDFs

The example below uses an array of HTML strings, creates a page for each one, and writes each returned PDF buffer to disk. It uses a bounded worker pool rather than opening a page for every input at once. Save it as render-html.mjs, install Puppeteer in the project, then run node render-html.mjs.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
#1 Best Overall
Elebase USB to USB C Adapter for iPhone 18 Pro Max,USBC Car Charger Adapter
  • Read Before You Buy — No Video Output: These adapters support charging and USB 2.0 data transfer, but cannot transmit video signals. Except for standard USB webcams (which use USB data only), they are not compatible with HDMI/DisplayPort cables, video-capable USB-C hubs, or docking stations with video output.
  • Convert USB-A Ports to USB-C: Designed to connect USB-C earphones, cables, flash drives, card readers, and other USB-C accessories to standard USB-A ports. Plug-and-play with no drivers or software required.
  • Aluminum Alloy Housing: Built with a sturdy aluminum alloy shell that aids in heat dissipation and protects against daily wear and scratches. Designed to maintain a stable and secure connection.
  • Compact & Travel-Friendly: The ultra-compact design allows the adapter to stay plugged into your device without blocking adjacent ports or adding bulk, reducing wear and tear on your original USB ports.
  • 12-Month Warranty: Backed by a 12-month manufacturer warranty for peace of mind. Designed to meet strict quality control standards for reliable everyday performance.
import puppeteer from 'puppeteer';
import { writeFile } from 'node:fs/promises';

const documents = [
  { name: 'first', html: '<!doctype html><html><body><h1>First report</h1></body></html>' },
  { name: 'second', html: '<!doctype html><html><body><h1>Second report</h1></body></html>' },
];

const concurrency = 3;
const outputs = new Array(documents.length);
let nextIndex = 0;

const browser = await puppeteer.launch();
try {
  async function worker() {
    while (true) {
      const index = nextIndex++;
      if (index >= documents.length) return;

      const { name, html } = documents[index];
      const page = await browser.newPage();
      try {
        await page.setContent(html, { waitUntil: 'networkidle0' });
        const pdf = await page.pdf({
          format: 'A4',
          printBackground: true,
          waitForFonts: true,
        });
        outputs[index] = pdf;
        await writeFile(`${name}.pdf`, pdf);
      } finally {
        await page.close();
      }
    }
  }

  await Promise.all(
    Array.from({ length: Math.min(concurrency, documents.length) }, () => worker()),
  );
} finally {
  await browser.close();
}

console.log(`Rendered ${outputs.length} PDFs.`);

In a JavaScript file, the HTML strings contain ordinary HTML markup; the entities shown inside the code block represent angle brackets for publication display. The browser is launched once and reused, while each job gets its own page. The page closes even if loading or PDF creation fails, and the browser closes after the worker pool settles. Set concurrency based on measurements on the actual host rather than assuming that more simultaneous pages are always better.

Choose the failure policy deliberately

With the worker code above, if a job rejects, Promise.all() rejects and the outer finally closes the browser. Other already-running workers may still finish their current work, but the batch is treated as failed. For a workflow that must keep successful PDFs when one input is bad, catch errors inside each worker, record the input name and error, and continue; report the failures separately instead of silently presenting a partial batch as complete.

Rank #2
Anker USB-C Hub, 5-in-1 USB Hub for Laptops, 4K HDMI Multiport Adapter
  • 5-in-1 USB-C Hub: Experience comprehensive connectivity featuring a Power Delivery input, two USB-A 2.0 ports, a USB-A 3.0 port, and an HDMI port. (Note: The USB-C power delivery input port is only for connecting an external wall charger to power your laptop and cannot power peripheral devices.)
  • 90W Pass-Through Charging: Achieve optimal charging with 90W pass-through power to your laptop, supported by a total input of 100W, with the hub reserving 10W for operational efficiency. (Note: Wall charger not included.)
  • Quick Data Transfers: Accelerate your productivity with rapid data transfers using a high-speed 5Gbps USB 3.0 port and two 480Mbps USB 2.0 ports.
  • 4K HDMI Display: Enhance your visual experience with a hub capable of delivering 4K resolution at 30Hz in both mirror and extend modes. Please note that this hub is compatible with MacBook (macOS 12 and newer), Windows 10 and 11, ChromeOS, and laptops equipped with DP Alt Mode and Power Delivery. Note: This device is not compatible with Linux.
  • What You Get: Anker USB-C Hub (5-in-1, 4K HDMI), welcome guide, 18-month warranty, and our friendly customer service.

Render HTML files from disk

For files, read each input as UTF-8 and pass its contents to page.setContent(). The rest of the page lifecycle is the same. For example, replace the in-memory documents definition with:

import { readFile } from 'node:fs/promises';

const inputPaths = ['input/one.html', 'input/two.html'];
const documents = await Promise.all(
  inputPaths.map(async (path, index) => ({
    name: `document-${index + 1}`,
    html: await readFile(path, 'utf8'),
  })),
);

Relative asset paths need special care. HTML passed through setContent() does not automatically acquire the same base URL that it would have when opened from its original file location. If the document references local images, stylesheets, or scripts by relative path, use absolute paths or set an appropriate base URL in the HTML, and make sure Chromium can access the resources. If the files rely on browser state such as authentication, configure that state for the pages before loading them.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #3
Sale
Anker USB C Hub, 7in1 Multi-Port USB Adapter, 4K@60Hz USBC to HDMI Splitter
  • Sleek 7-in-1 USB-C Hub: Features an HDMI port, two USB-A 3.0 ports, and a USB-C data port, each providing 5Gbps transfer speeds. It also includes a USB-C PD input port for charging up to 100W and dual SD and TF card slots, all in a compact design.
  • Flawless 4K@60Hz Video with HDMI: Delivers exceptional clarity and smoothness with its 4K@60Hz HDMI port, making it ideal for high-definition presentations and entertainment. (Note: Only the HDMI port supports video projection; the USB-C port is for data transfer only.)
  • Double Up on Efficiency: The two USB-A 3.0 ports and a USB-C port support a fast 5Gbps data rate, significantly boosting your transfer speeds and improving productivity.
  • Fast and Reliable 85W Charging: Offers high-capacity, speedy charging for laptops up to 85W, so you spend less time tethered to an outlet and more time being productive.
  • What You Get: Anker USB-C Hub (7-in-1), welcome guide, 18-month warranty, and our friendly customer service.

Choose load completion and print styling

Wait for the resources the document actually needs

The example waits for networkidle0 before printing, which is useful when external assets need time to load. It may be unsuitable for pages that keep network connections active. Select the page.setContent() wait condition to suit the document; if an important element signals readiness more reliably, wait for that selector before calling page.pdf(). A timeout or rejected load should be surfaced as a per-document failure, not converted into an apparently valid PDF.

Print media and screen media are different

PDF generation uses print media by default. That means print-specific CSS may apply, and screen-only styling may not appear as it does in a browser tab. If the desired output is the screen design, call await page.emulateMediaType('screen') before page.pdf(). For a print document, leave the default media in place and inspect the print styles.

Rank #4
Sale
UGREEN USB to USB C Adapter Combo 4-Pack, 10Gbps USB C Converter Space Gray
  • Dual Converters, Infinite Potential:Includes 2× USB C male to USB A female adapters and 2× USB A male to USB C female adapters. Perfect for a wide range of uses—tablets with Bluetooth keyboards, expand USB ports on macbook, and more. Two different converters for all your daily needs
  • Next-Level 10Gbps & 3A Charging: No more slow 480Mbps, this usb to usb c adapter has a transfer speed of up to 10Gbps, allowing you to do more transferring in less time. This usb adapter fits both USB A and USB C charger, supporting up to 3A fast charging
  • Upgraded Exquisite Craftsmanship: With an aluminum alloy housing and metal connector, the usbc to usb adapter is extremely durable and sturdy. Rigorously tested to withstand more than 10,000 times of plugging and unplugging, ensuring long-lasting performance
  • Broad Compatible: The usb c to usb adapter widely supports all USB C/ USB A devices like laptops, tablets, cellphones, car chargers, and phone chargers. Such as compatible with MacBook Pro/Air 2023/2022, Thunderbolt 4/3 Devices,Apple MagSafe Watch 9/8/7/SE/Ultra, iPad Pro 2022/2021, Samsung Galaxy S23/S20/S10, and iPhone 17/16/15 Pro. Plug and play
  • Please Note: To reach 10Gbps speed, keep the cable under 3.3 ft. For USB A Male to USB C adapters, try flipping the USB C connector. USB C Male to USB A adapters support bidirectional 10Gbps transfer within 3.3 ft

Set PDF options to match the document

Puppeteer’s documented defaults include Letter paper, no printed background graphics, font waiting enabled, and a 30-second PDF timeout. The sample explicitly chooses A4, enables backgrounds, and keeps font waiting on. Review the installed version’s PDFOptions API for paper dimensions, orientation, margins, page ranges, scale, headers and footers, transparency, and timeout behavior.

  • Use printBackground: true when the PDF must retain background colors or images.
  • Use preferCSSPageSize: true when the document’s CSS @page size should take precedence over the API’s format or dimensions.
  • Use explicit margins or page ranges when the output must follow a defined print layout.
  • For more faithful print colors, the Puppeteer documentation notes the CSS property -webkit-print-color-adjust.

One PDF per file or one combined PDF?

Choose the output structure before implementing the batch. Separate files are simplest when each HTML file represents a report, invoice, or other independently consumed document. Preserve the input order in the result array if you later merge outputs: asynchronous jobs may finish in a different order, but the example stores each output at its original index.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Best Value
Anker USB C Hub, 5-in-1 USBC to HDMI Splitter with 4K Display
  • 5-in-1 Connectivity: Equipped with a 4K HDMI port, a 5 Gbps USB-C data port, two 5 Gbps USB-A ports, and a USB C 100W PD-IN port. Note: The USB C 100W PD-IN port supports only charging and does not support data transfer devices such as headphones or speakers.
  • Powerful Pass-Through Charging: Supports up to 85W pass-through charging so you can power up your laptop while you use the hub. Note: Pass-through charging requires a charger (not included). Note: To achieve full power for iPad, we recommend using a 45W wall charger.
  • Transfer Files in Seconds: Move files to and from your laptop at speeds of up to 5 Gbps via the USB-C and USB-A data ports. Note: The USB C 5Gbps Data port does not support video output.
  • HD Display: Connect to the HDMI port to stream or mirror content to an external monitor in resolutions of up to 4K@30Hz. Note: The USB-C ports do not support video output.
  • What You Get: Anker 332 USB-C Hub (5-in-1), welcome guide, our worry-free 18-month warranty, and friendly customer service.

If one combined PDF is required, either merge the generated PDF byte arrays in a dedicated PDF-processing stage or compose a single HTML document and call page.pdf() once. A single HTML document is convenient when page breaks, shared headers, and consistent styling can be controlled in HTML. A merge stage is appropriate when the inputs must stay separate or have already been rendered. Puppeteer’s page PDF method does not perform that merge itself.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Parallel rendering, reliability, and resource use

A page per input is easy to reason about, and independent jobs can be awaited with Promise.all(). An unbounded Promise.all(documents.map(...)) can, however, open too many pages for a large batch. Use a worker pool or another bounded scheduler and tune its limit against the memory and CPU available on the machine. The Puppeteer documentation does not provide a universal concurrency setting or a throughput guarantee.

Reuse one browser for a batch and close every page after its render. Put browser shutdown in a finally block so failures do not leave a long-running process holding browser resources. If pages should not share cookies or cache, use separate browser contexts; Puppeteer documents that separate browser contexts do not share those values. If the documents need common authentication or cookies, configure them in the context used by their pages.

Troubleshooting common failures

  • PDF is blank or missing images: the page may have been printed before its content or external assets finished loading. Choose an appropriate wait condition, wait for a required selector, and confirm that referenced assets are reachable from Chromium.
  • Styles differ from the browser view: PDF rendering uses print media by default. Use emulateMediaType('screen') before printing only when screen styling is the intended output; otherwise correct the print CSS.
  • Background colors or images are absent: background printing is off by default. Set printBackground: true.
  • Paper size or pagination is unexpected: the default format is Letter. Set the desired format, dimensions, margins, or CSS page-size preference explicitly and inspect the @page rules.
  • Fonts appear late or differently: font waiting is enabled by default, but the font resources still need to load successfully. Check the font URLs and allow sufficient time for external resources.
  • Large batches become slow or fail under load: reduce the worker count and observe the host’s memory and CPU use. No concurrency value is best for every input set or host.
  • Some PDFs exist but the batch exits with an error: one rendering promise may have rejected. Log failures with their input names and decide whether the workflow should fail as a whole or retain successful outputs with an explicit failure report.
  • Several PDFs were created but the recipient expects one: add a merge stage, or render a composed HTML document. Multiple calls to Page.pdf() do not produce a combined document automatically.

Or skip the browser setup

If your HTML is already available at a public URL and you want a screenshot or PDF capture of that page, ScreenshotNeo offers a one-request capture API. It is not a local-file batch renderer or a PDF-merging step, so use Puppeteer above for local HTML inputs and combined-document workflows. See the ScreenshotNeo documentation for API details.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

ScreenshotNeo removes cookie banners, newsletter popups, and chat widgets before capture; bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents take screenshots, and the Free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. Sign up free for 1,000 screenshots a month, with no card required.

Official Puppeteer references

These API references identify Puppeteer version 25.12.0 in the cited results; check the documentation matching your installed release because method details and defaults can change.

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.