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

The right way to convert HTML to PDF in JavaScript depends on where the code runs. For a user saving the page they are viewing, use the browser’s print flow and print-specific CSS. For a client-side download of one element, html2pdf.js is convenient but produces image-based pages. For server-side generation in Node.js, use Puppeteer’s page.pdf(). Use pdf-lib when you need to create or edit PDF objects—not to render arbitrary HTML and CSS.

Choose the approach for your runtime and output

Approach Runs where Best fit Main trade-off
Browser print In the user’s browser Let users print or save the current page through browser controls The browser controls the dialog and final settings; the page needs a print layout.
html2pdf.js Browser only A simple client-side download for an element or page It renders content as images, so text is not selectable or searchable; reflow and canvas-size limits can affect output.
Puppeteer page.pdf() Node.js controlling a browser Automated or server-side PDF generation from a rendered page PDF uses print CSS by default; asset readiness, print styles, colors, and browser lifecycle need attention.
pdf-lib Browser, Node.js, Deno, React Native, and other supported JavaScript environments Creating or editing PDF pages, text, images, or forms; merging or splitting files It is not an HTML/CSS layout engine.

These tools solve different problems. Decide first whether the conversion should happen in the visitor’s browser or on a server, and whether the PDF needs selectable text and faithful page layout.

Let users print or save the current page

When the user is already viewing the HTML page, call window.print() in response to a user action. The browser presents its print interface, where the user can choose a PDF destination and settings. Add a print stylesheet so navigation, controls, and other screen-only elements do not clutter the document.

const printButton = document.querySelector('#print-button');

printButton.addEventListener('click', () => {
  window.print();
});
@media print {
  .site-header,
  .site-nav,
  .print-button,
  .screen-only {
    display: none !important;
  }

  body {
    color: #000;
    background: #fff;
  }

  .report-section {
    break-inside: avoid;
  }
}

Keep the printable content in the page’s normal document structure, and test the print preview in each browser you support. Browser-specific print behavior and available destination settings are controlled by the browser, not by window.print().

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.

Download an element with html2pdf.js

html2pdf.js is a browser-side convenience pipeline built on html2canvas and jsPDF. Install it with npm install --save html2pdf.js, then call it on the element to export:

import html2pdf from 'html2pdf.js';

const element = document.getElementById('element-to-print');

if (!element) {
  throw new Error('Could not find #element-to-print');
}

html2pdf(element);

This package must run in a browser; it is not a Node.js server-side renderer. Its documented output is image-based: the PDF’s content is not selectable or searchable as text. It may resize or reflow content to fit pages, and very large canvases can exceed browser limits and produce blank output. The project also notes HTML rendering and cloned-node/CSS issues. Test long pages, web fonts, images, page breaks, and complex styling in the actual browser where users will run the feature.

Generate a PDF on the server with Puppeteer

Puppeteer launches a browser that can load a URL and write the rendered page to a PDF. Install Puppeteer in your Node.js project, then use a lifecycle that closes the browser even if navigation or PDF writing fails:

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.
const puppeteer = require('puppeteer');

async function savePageAsPdf(url, outputPath) {
  const browser = await puppeteer.launch();

  try {
    const page = await browser.newPage();
    await page.goto(url, { waitUntil: 'networkidle2' });
    await page.pdf({ path: outputPath });
  } finally {
    await browser.close();
  }
}

savePageAsPdf('https://example.com/report', 'report.pdf')
  .catch((error) => {
    console.error('PDF generation failed:', error);
    process.exitCode = 1;
  });

Puppeteer’s Page.pdf() documentation says PDF generation uses print CSS media by default and waits for fonts by default. Its PDF guide documents the launch, page, navigation, PDF, and close workflow.

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

Choose print or screen media deliberately

For a PDF that should reflect the print stylesheet, keep the default media mode. If the design depends on screen styles, emulate screen media before creating the PDF:

await page.emulateMediaType('screen');
await page.pdf({ path: 'report.pdf' });

Control page size, margins, and page breaks

Define page rules in CSS when the layout itself should control paper size and breaks. For example:

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.
@media print {
  @page {
    size: A4;
    margin: 16mm;
  }

  .new-page {
    break-before: page;
  }

  .keep-together {
    break-inside: avoid;
  }
}

You can also pass PDF options such as format and margins to page.pdf(). Avoid setting conflicting paper dimensions in both CSS and the call unless you have verified which should govern your output.

Preserve print colors when required

Puppeteer documents that printing modifies colors by default. If exact CSS colors matter to the document, the API documentation points to -webkit-print-color-adjust:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
@media print {
  html {
    -webkit-print-color-adjust: exact;
  }
}

Color adjustment can affect how a document prints, so use it only when preserving the designed colors is more important than print-friendly adjustments.

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

Wait for the page assets your PDF needs

networkidle2 is one navigation condition, not a guarantee that every application-specific render is complete. Pages that load data after navigation, animate content, or lazy-load images may need an explicit readiness signal. Wait for a selector or application state before calling page.pdf(), and check that images and fonts appear in the result. Puppeteer’s documented font-wait behavior applies to PDF generation, but it does not replace waiting for your own data and page logic.

Use pdf-lib to create or edit PDF documents

pdf-lib is appropriate when you need to work directly with PDF structures—for example, creating pages and drawing text or images, embedding fonts, filling forms, or modifying, merging, and splitting existing PDFs. The project documents support for browser and server JavaScript environments. Its creation workflow looks like this:

import { PDFDocument, StandardFonts, rgb } from 'pdf-lib';
import fs from 'node:fs/promises';

const pdfDoc = await PDFDocument.create();
const page = pdfDoc.addPage();
const font = await pdfDoc.embedFont(StandardFonts.Helvetica);

page.drawText('Quarterly report', {
  x: 50,
  y: 750,
  size: 18,
  font,
  color: rgb(0, 0, 0),
});

const pdfBytes = await pdfDoc.save();
await fs.writeFile('report.pdf', pdfBytes);

This draws PDF content directly. If your input is an arbitrary HTML/CSS page and you need browser-like layout, use a browser-based renderer such as Puppeteer instead.

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.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

For a rendered website screenshot or PDF without managing browser automation, ScreenshotNeo provides a one-call API. It can return a PDF, and its cleanup options remove cookie/consent banners, newsletter popups, and chat widgets before capture. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed; response headers report the page verdict and billing status. An MCP server provides screenshot tools for AI agents.

curl -G "https://api.screenshotneo.com/v1/shot" 
  -d access_key=YOUR_API_KEY 
  --data-urlencode url=https://example.com 
  -o page.pdf

See the ScreenshotNeo API documentation for request options. The free plan includes 1,000 screenshots a month without a card; paid plans start at $5 for 3,000. This is a website-capture service, rather than a replacement for generating a PDF from an HTML string you already hold in your application. Sign up for 1,000 free screenshots a month—no card required.

Troubleshoot common conversion problems

Symptom Likely cause What to try
Text in an html2pdf.js PDF cannot be selected or searched The package renders the page content as an image. Use browser printing or Puppeteer when searchable text is required.
A long html2pdf.js export is blank or incomplete The rendered canvas may exceed browser dimension limits, or the page may trigger a rendering issue. Test a shorter document, simplify large content, and check the project’s documented HTML/CSS and cloned-node limitations.
The PDF has the wrong layout Puppeteer uses print media by default, or the print stylesheet differs from the screen design. Adjust @media print, or call page.emulateMediaType('screen') before PDF generation if screen styling is intended.
Images or application content are missing Navigation completed before lazy-loaded assets or app rendering finished. Wait for an application-specific selector or readiness state; verify the page has loaded the required assets before calling page.pdf().
Colors look lighter or different in a Puppeteer PDF Print color adjustment modifies colors by default. For designs that require exact colors, set -webkit-print-color-adjust: exact in print CSS and inspect the output.
Browser printing includes menus or buttons The page has no print-specific rules for screen-only UI. Hide those elements under @media print and check print preview in supported browsers.
pdf-lib does not reproduce the HTML layout pdf-lib draws and edits PDF content; it does not render arbitrary HTML/CSS. Use Puppeteer or a browser print flow for HTML layout, or draw the intended PDF elements directly with pdf-lib.
The browser does not close after a failed Puppeteer job Cleanup was omitted from an error path. Place browser.close() in a finally block, as in the example above.

Reliability, performance, and cost considerations

The reviewed project documentation does not establish comparative performance benchmarks, deployment costs, concurrency limits, or hosting requirements for these approaches. Do not assume a short example is sufficient for a production service: test the exact pages, assets, fonts, and styles your application will convert, and ensure browser resources are cleaned up after each job. In the browser, large image-based exports are subject to canvas constraints; with Puppeteer, generation depends on launching and controlling a browser process and waiting for the page state your output requires.

Frequently Asked Questions

Can I convert an HTML string to PDF with Puppeteer?

Yes. Load the HTML into a Puppeteer page, wait for any required assets or application rendering, then call page.pdf(). Use this when you need browser-rendered HTML/CSS rather than drawing PDF objects directly.

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

Which approach produces searchable PDF text?

The html2pdf.js project documents image-based output, so its text is not searchable or selectable. Browser printing or Puppeteer is a better fit when preserving rendered text matters.

Can pdf-lib convert a webpage’s CSS layout into a PDF?

No. It creates and modifies PDF content such as pages, text, images, and forms; it is not a browser layout engine for arbitrary HTML and CSS.

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.