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

Use Playwright’s Chromium page.pdf() API to save each URL as its own PDF; loop through a URL list, choose a readiness condition for each site, and use a separate output path per page. PDF export uses print CSS by default. To produce a full-page raster image instead, use page.screenshot({ fullPage: true })—that is a different output, not a PDF.

Batch URLs into separate PDFs

The following Node.js pattern processes URLs sequentially in one BrowserContext, creating and closing a page for each URL. Sequential processing is a straightforward starting point for modest batches because it keeps resource use predictable. It is an implementation pattern based on the documented APIs, not a tested script; adapt navigation readiness, authentication, and error handling to the sites you capture.

import { chromium } from 'playwright';

const urls = [
  'https://example.com/',
  'https://playwright.dev/',
];

const browser = await chromium.launch();
const context = await browser.newContext();

try {
  for (const [index, url] of urls.entries()) {
    const page = await context.newPage();
    try {
      await page.goto(url, { waitUntil: 'load' });
      // Replace or supplement this with a site-specific readiness condition where needed.
      const filename = `capture-${String(index + 1).padStart(3, '0')}.pdf`;
      await page.pdf({
        path: filename,
        format: 'A4',
        printBackground: true,
      });
    } catch (error) {
      console.error(`Capture failed for ${url}:`, error);
    } finally {
      await page.close();
    }
  }
} finally {
  await context.close();
  await browser.close();
}

The filenames are deterministic by list position, so the first URL becomes capture-001.pdf. If filenames should identify their source, build them from a sanitized hostname and retain an index to avoid collisions. Create the destination directory before running the script if you change the output paths to include one.

Choose print or screen styling

page.pdf() generates a PDF using print CSS media by default. Print styles may hide navigation, change typography, or alter colors compared with what a visitor sees on screen. If the PDF should use screen styling, set the page media before generating it:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
await page.emulateMedia({ media: 'screen' });
await page.pdf({ path: 'screen-layout.pdf', format: 'A4', printBackground: true });

For print-oriented documents, leave the default media in place and review the site’s print stylesheet. When exact colors matter in print, the Playwright API documentation notes the CSS property -webkit-print-color-adjust. The page’s CSS @page rules can also affect sizing: preferCSSPageSize controls whether CSS page size takes precedence over the PDF options.

Set PDF page size and pagination

Use format for a standard paper size, or specify dimensions, and set margins, background printing, scale, and page ranges where needed. Supported option names and behavior are documented in the Playwright Page API.

  • format: choose a paper format such as 'A4'.
  • width and height: define page dimensions when a named format is not appropriate.
  • margin: set top, right, bottom, and left margins.
  • printBackground: include background graphics and colors; PDF backgrounds are not printed by default.
  • scale: adjust the scale of the page content.
  • pageRanges: export selected page ranges.
  • preferCSSPageSize: allow CSS @page sizing to take precedence.

For example, choose the paper format and margins explicitly when uniform output dimensions matter across URLs:

await page.pdf({
  path: 'report.pdf',
  format: 'A4',
  margin: { top: '12mm', right: '10mm', bottom: '12mm', left: '10mm' },
  printBackground: true,
  preferCSSPageSize: true,
});

Check the resulting PDF rather than assuming every site’s print CSS will produce the same pagination. Long pages, fixed elements, and site-specific print rules can affect page breaks and appearance.

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

Wait for the content you actually need

waitUntil: 'load' waits for the page load event, but it does not guarantee that an application has finished rendering data or that lazy-loaded media has appeared. For pages with client-rendered content, wait for a meaningful selector or another site-specific condition before exporting. For example:

await page.goto(url, { waitUntil: 'load' });
await page.locator('main article').waitFor({ state: 'visible' });
await page.pdf({ path: filename, format: 'A4', printBackground: true });

Use a selector that represents the content required for that site; a generic delay can waste time and still capture too early. If authentication is needed, configure the browser context or page appropriately before navigation. Sites that defer images until scrolling may require a site-specific approach to make those images load; the basic loop does not guarantee that lazy media will be present.

PDFs and full-page screenshots are different outputs

Need Playwright API Result and relevant controls
Paginated document page.pdf() PDF pages sized for print; print CSS is the default. Configure paper size, margins, background printing, page ranges, scaling, and CSS page-size precedence.
One tall image of the page page.screenshot({ fullPage: true }) Raster image of the full scrollable page rather than paper pagination. Configure image type, quality where supported, scale, animation behavior, and output path.
Visible viewport or selected region page.screenshot() Image capture can target the viewport or a clip/element instead of the entire scrollable page.

Playwright documents full-page screenshot mode as capturing the full scrollable page instead of only the visible viewport. See the screenshot options for available settings. A full-page screenshot is not a substitute for a multi-page PDF when paper-sized pages or pagination are required.

Scale the batch without losing control

A BrowserContext can host multiple pages, and context.pages() exposes the pages in that context. The sequential pattern above is a good baseline when predictable resource use matters. If you need concurrency, use a bounded worker pool rather than opening an unbounded number of pages at once, then measure resource use in the environment where the job will run. Playwright’s documentation establishes multiple-page support but does not prescribe a universal safe concurrency limit.

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.

Keep failures isolated per URL, as in the example’s per-page try/catch, so one navigation failure does not prevent the rest of the list from being processed. Record the URL alongside any error and check that every expected output file exists and opens before treating the batch as complete.

Make repeated captures more reliable

Browser rendering can vary with the host operating system, browser version and settings, hardware, power source, and headless mode. For repeatable batches, keep the Playwright and browser runtime, launch settings, host environment, viewport, and capture options consistent, then inspect representative outputs. Check the API documentation matching your installed Playwright version when selecting a runtime; PDF generation is supported in Chromium.

  • Choose an explicit paper format, margins, and media mode instead of relying on unintended site defaults.
  • Use a content-based readiness condition for pages that render after the load event.
  • Review sample PDFs for missing content, unexpected print styles, clipping, and page breaks before running a large batch.
  • Do not assume a particular throughput or safe parallelism level; it depends on the pages and execution environment.

Use the CLI for one-off captures

Playwright’s CLI reference includes screenshot, screenshot --full-page, and pdf commands with optional filenames. The CLI can be convenient for an individual page, while a URL-driven script is better suited to repeatable batches that need consistent settings, per-URL files, and error handling. See the Playwright CLI reference for command syntax.

Troubleshoot common batch failures

The PDF looks different from the browser

PDF export uses print CSS by default. If you want screen styling, call page.emulateMedia({ media: 'screen' }) before page.pdf(). If print layout is intended, inspect the site’s print stylesheet and its CSS @page rules.

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

Background colors or images are missing

Set printBackground: true. If exact print colors are important, review the site CSS and its -webkit-print-color-adjust behavior.

The PDF is blank or missing dynamic content

The page may have fired the load event before its application content appeared. Wait for a site-specific selector or readiness condition after navigation, and log navigation errors for the affected URL.

Some images are absent

Images may be lazy-loaded or dependent on scrolling. The basic example does not force every site to load deferred media; use a site-specific approach and inspect the output before processing the whole batch.

Only some URLs produce files

Check the logged URL and error, confirm that the destination path is writable, and handle navigation or PDF-generation failures per page. A per-URL failure should not silently count as a successful capture.

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

The output varies between runs

Differences can come from the runtime and host environment, including browser version, settings, hardware, and headless mode. Keep those conditions fixed where possible and compare sample outputs.

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

Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server. For a URL-driven screenshot call, it returns an image or PDF; its PDF options include paper size, margins, landscape, and page ranges. This is a service alternative to operating your own Playwright browser workflow, not a Playwright PDF implementation.

With an access key, the one-request cURL form is:

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

See the ScreenshotNeo API documentation for request details. It removes cookie banners, newsletter popups, and chat widgets before capture; bot checks, blank pages, and failed loads are not billed. Its MCP server lets AI agents take screenshots, and the Free plan includes 1,000 screenshots per month without a card. Paid plans start at $5 for 3,000 screenshots. Sign up free to get started.

Frequently Asked Questions

Can a single Playwright PDF contain several URLs?

The batch pattern here saves one PDF per URL. Combining pages from different URLs into one document requires a separate PDF-merging step.

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

Can Playwright capture a PDF with Chromium only?

The Page API documents PDF generation as supported in Chromium. Check the API documentation for the Playwright version and browser runtime you install.

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.