Skip to main content
Tutorial8 min read

How to Save Multiple Webpages as PDFs: Batch Workflow Guide

A complete guide to batch-saving multiple webpages as PDFs — from extension-based workflows for occasional users to Puppeteer scripts for hundreds of pages.

Batch ExportAutomationPuppeteer
Web-PDF.com

Saving one webpage as a PDF takes fifteen seconds. Saving thirty takes eight minutes of repetitive clicking — if you do them one at a time. The issue isn't that it's hard, it's that it doesn't scale. Any workflow that requires manual repetition per URL is a workflow waiting to be replaced.

There are several ways to batch-save multiple webpages as PDFs, ranging from extension-based approaches for occasional users to scripted automation for developers handling hundreds of pages.

Why Chrome's Native Print Dialog Doesn't Scale

Chrome's print dialog (Ctrl+P) was built for single-page use. It requires you to open the tab, trigger the print dialog, select the destination and settings, click Save and name the file, then repeat for the next page. There's no way to queue tabs or point it at a list of URLs. Even with muscle memory, each page takes 15–30 seconds of active attention.

For comparing the native print dialog against dedicated extension tools, the single-page speed difference is small. But the batch capability gap is significant.

Method 1 — Browser Extensions with Multi-Tab Support

GoFullPage (with batch workflow)

GoFullPage doesn't have a single-click "export all tabs" feature in its free version, but with workflow discipline it handles moderate batches:

  1. Open all target pages as tabs.
  2. Click the GoFullPage icon on the first tab — it captures and queues the download.
  3. Move to the next tab and repeat.
  4. All PDFs download to your default folder.

The manual-per-tab approach still requires a click per page, but GoFullPage captures the full page length without requiring a print dialog each time. For a batch of 10–20 pages, this is faster than the native print method.

Tab Save and similar multi-tab extensions

Extensions like Tab Save are purpose-built for multi-tab batch operations. They let you select tabs from a list, export them all as PDFs in one operation, and name files automatically using the page title and date. For choosing between different Chrome extension approaches, batch capability is a distinguishing factor worth checking before installing.

Method 2 — Puppeteer Script (Best for Large Batches)

Puppeteer is the right tool when you have a URL list and want fully automated, hands-off conversion. It runs headless Chromium — the same rendering engine as Chrome — so the output is identical to Chrome's native PDF.

Basic batch PDF script

const puppeteer = require('puppeteer');
const fs = require('fs');

const urls = [
  'https://example.com/page-1',
  'https://example.com/page-2',
  'https://example.com/page-3',
];

async function batchToPDF(urls, outputDir) {
  const browser = await puppeteer.launch();

  for (let i = 0; i < urls.length; i++) {
    const page = await browser.newPage();
    await page.goto(urls[i], { waitUntil: 'networkidle0' });

    const filename = 'page-' + String(i + 1).padStart(3, '0') + '.pdf';
    await page.pdf({
      path: outputDir + '/' + filename,
      format: 'A4',
      printBackground: true,
      margin: { top: '20mm', bottom: '20mm', left: '15mm', right: '15mm' }
    });

    await page.close();
    console.log('Saved: ' + filename);
  }

  await browser.close();
}

batchToPDF(urls, './output');

This script opens each URL, waits for the page to fully load (including lazy-loaded content), and saves the PDF. The networkidle0 wait condition ensures dynamic content has time to render before capture.

To load URLs from a file instead of hardcoding them:

const urls = fs.readFileSync('urls.txt', 'utf8')
  .split('
')
  .filter(line => line.trim().length > 0);

Adding delays for rate limiting

If you're batch-converting pages from a public site, add a delay between requests to avoid triggering rate limits. Place this inside the loop after each page.close() call:

await new Promise(resolve => setTimeout(resolve, 2000));

Method 3 — Command Line with Headless Chrome

For batch conversion without writing a Node.js script, headless Chrome can convert pages from the command line. For batch conversion, wrap it in a shell loop:

while IFS= read -r url; do
  filename=$(echo "$url" | sed 's/[^a-zA-Z0-9]/-/g').pdf
  google-chrome --headless --disable-gpu --print-to-pdf="./output/${filename}" "$url"
done < urls.txt

This is faster to set up than Puppeteer for one-off batch jobs where you don't need fine-grained control over rendering settings.

Merging Multiple PDFs into One Document

Once you have individual PDFs from a batch conversion, you often need them as a single document.

  • PDF24 (web app, free): Upload multiple PDFs, set the order, download the merged file.
  • macOS Preview: Open the first PDF, then drag other PDFs into the thumbnail sidebar. Export as PDF when done.
  • PDFsam Basic (Windows/Linux): Free desktop app specifically for split and merge operations. Handles large batches reliably.

Scripted merging

For automated pipelines, Python's pypdf library handles merging programmatically:

from pypdf import PdfWriter

merger = PdfWriter()
pdf_files = ['page-001.pdf', 'page-002.pdf', 'page-003.pdf']

for pdf in pdf_files:
    merger.append(pdf)

merger.write('combined.pdf')
merger.close()

Handling Dynamic and Authenticated Pages

Pages with lazy-loaded content

Add an explicit scroll step in Puppeteer for pages with scroll-triggered loading:

await page.evaluate(async () => {
  await new Promise(resolve => {
    let totalHeight = 0;
    const distance = 100;
    const timer = setInterval(() => {
      window.scrollBy(0, distance);
      totalHeight += distance;
      if (totalHeight >= document.body.scrollHeight) {
        clearInterval(timer);
        resolve();
      }
    }, 100);
  });
});

Pages behind login

Puppeteer can authenticate by injecting cookies from an existing browser session. Export cookies from your authenticated Chrome session using a cookies export extension (EditThisCookie), save as JSON, and reference in the script:

const cookies = JSON.parse(fs.readFileSync('cookies.json', 'utf8'));
await page.setCookie(...cookies);

Naming and Organising the Output

Apply a naming convention before you start. Use the page title extracted from the DOM, sanitize special characters, and prepend the date:

const title = (await page.title()).replace(/[^a-zA-Z0-9 ]/g, '').trim().replace(/ /g, '-');
const filename = '2026-04-20_' + title + '.pdf';

For naming conventions and folder organisation that pair with batch output, archiving web content for long-term offline reading covers how to structure a collection that actually stays useful over time.

Choosing the Right Method

MethodBest forSetup requiredPages per hour
GoFullPage manual batch< 20 pages, occasionalNone~40
Tab Save extension< 50 pages, in-browserInstall extension~80
Puppeteer script50+ pages, recurringNode.js, npm200+
Headless Chrome CLIOne-off batchesChrome installed150+
Cloud PDF APILarge volume, team useAPI integrationUnlimited

For recurring workflows — a weekly competitive analysis, a regulatory compliance archive — the upfront cost of a Puppeteer script pays back quickly. For occasional use, an extension is the faster path to getting started.

Frequently Asked Questions

Can Chrome save multiple tabs as PDFs at once?

Not natively. You need an extension (Tab Save, GoFullPage) or a script (Puppeteer, headless Chrome CLI) to batch-save multiple tabs or URLs.

What's the fastest batch method for a large URL list?

Puppeteer or headless Chrome CLI — both handle hundreds of pages automatically once set up, with no manual steps per page.

How do I merge the resulting PDFs into one document?

Use PDF24 (free web app), macOS Preview, PDFsam Basic (Windows), or the Python pypdf library for scripted merging.

Can batch tools handle pages behind a login?

Browser extensions handle authenticated pages because they run in your active browser session. Puppeteer can use exported cookies. Cloud services generally cannot.

How do I handle lazy-loaded content in batch conversions?

Use Puppeteer's waitUntil: 'networkidle0' option and add a scroll step to trigger lazy-loaded elements before capturing the PDF.