ScreenshotNeo

BlogHow-to

How to Capture a Website Screenshot with a Custom Paper Size for a Report

Choose an image or custom-size PDF, then capture it with Playwright or Chrome Headless. Learn how paper dimensions, print CSS, and page settings affect the result.

By the ScreenshotNeo team4 October 20269 min read

First decide what your report needs: a viewport image, a full-page image, an image of one element, or a paginated PDF on custom paper. A screenshot image has pixel dimensions; it does not have physical paper dimensions. For a PDF with a custom paper size, use a browser print-to-PDF operation and set the page width and height. This guide uses Playwright for the runnable examples and also shows Chrome Headless, cURL, Python, Node.js, and ScreenshotNeo.

1. Choose the output your report needs

Output Use it when Size control
Viewport screenshot You need what is visible in the browser window. Viewport width and height in pixels.
Full-page screenshot You need a tall image of the page’s scrollable content. Viewport width plus the page’s full scrollable height.
Element screenshot You need a particular chart, table, or report section. Element bounds in pixels.
PDF on custom paper You need a printable or paginated report document. Physical or pixel page width and height, margins, and print CSS.

Playwright separates image capture with page.screenshot() from PDF output with page.pdf(). Its screenshot API supports viewport or full-page capture, and its documentation also covers element screenshots. PDF output uses print CSS media. [Playwright screenshots] [Playwright Page API] [Playwright screenshots and PDF]

2. Set up a Playwright capture

Install Playwright and its Chromium browser in a new Node.js project:

npm init -y
npm install playwright
npx playwright install chromium

Save the following as capture-report.mjs. It writes a full-page PNG and a PDF whose paper is 210 mm wide by 297 mm high. Change the URL and dimensions to suit your report. The example waits for the page load event and then allows a short settling delay; for pages with known dynamic content, wait for a specific selector instead, as shown in the next section.

import { chromium } from 'playwright';

const url = process.argv[2] ?? 'https://example.com';
const browser = await chromium.launch({ headless: true });
const page = await browser.newPage({
  viewport: { width: 1280, height: 900 },
  deviceScaleFactor: 1,
});

try {
  await page.goto(url, { waitUntil: 'load', timeout: 60_000 });
  await page.waitForTimeout(1_000);

  // Raster image: full scrollable page; paper dimensions do not apply.
  await page.screenshot({ path: 'report.png', fullPage: true });

  // PDF: custom physical page size, in millimeters.
  await page.pdf({
    path: 'report.pdf',
    width: '210mm',
    height: '297mm',
    printBackground: true,
    margin: { top: '10mm', right: '10mm', bottom: '10mm', left: '10mm' },
    preferCSSPageSize: false,
  });
} finally {
  await browser.close();
}

Run it with:

node capture-report.mjs https://example.com

The PDF is one or more pages of the requested size depending on document content and pagination. Inspect the saved file: print styles, page breaks, margins, and scaling can change how the page appears compared with the screen.

3. Configure custom PDF paper and print layout

Playwright’s page.pdf() accepts width and height with units such as px, in, cm, and mm. It also accepts standard paper formats including A4 and Letter. Choose one approach: explicit width and height for a custom size, or a named format for standard paper. [Playwright Page API]

// Exact custom paper: 8.5 by 13 inches.
await page.pdf({
  path: 'custom.pdf',
  width: '8.5in',
  height: '13in',
  printBackground: true,
  margin: { top: '0.4in', right: '0.4in', bottom: '0.4in', left: '0.4in' },
});

// Standard named format alternative.
await page.pdf({ path: 'letter.pdf', format: 'Letter', printBackground: true });

Dimensions describe the paper box. Margins reserve space inside that box for content. For landscape output, swap the width and height or use the API’s landscape option where applicable; avoid setting contradictory dimensions and orientation without checking the resulting PDF. A page’s CSS can also set a paper size:

@media print {
  @page {
    size: 210mm 297mm;
    margin: 10mm;
  }

  body {
    -webkit-print-color-adjust: exact;
    print-color-adjust: exact;
  }

  .screen-only, .cookie-banner {
    display: none !important;
  }

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

page.pdf() uses print CSS media. With preferCSSPageSize: true, a CSS @page size takes priority over the API’s width, height, or format values. With it false, the API paper size is used and CSS may be scaled to fit. Use one source of truth for page size where possible, and verify the output dimensions and breaks. The exact interaction of print rules with a particular site depends on that site’s styles. [Playwright Page API]

4. Wait for dynamic content and capture images

A successful navigation does not guarantee that a chart, client-rendered report, or lazy-loaded image is ready. Prefer a meaningful selector or application-ready condition over an arbitrary long delay. For example:

await page.goto(url, { waitUntil: 'domcontentloaded', timeout: 60_000 });
await page.locator('[data-report-ready="true"]').waitFor({ state: 'visible', timeout: 30_000 });
await page.screenshot({ path: 'report-element.png', selector: '.report-card' });
await page.pdf({
  path: 'report.pdf',
  width: '210mm',
  height: '297mm',
  printBackground: true,
});

Replace the selector with one the target page actually renders. If there is no reliable readiness marker, wait for a known heading, chart, or network state and inspect the output. For an image, use fullPage: true for the complete scrollable page; omit it for the viewport. For a focused capture, target a locator or use the element screenshot API. These are pixel captures, so later placement into a report may scale them and affect sharpness.

For stronger image detail, set a larger viewport or device scale factor when creating the page, then check the output’s pixel dimensions and memory use. A larger raster image can consume substantially more memory and storage. Device scale does not change PDF paper dimensions.

5. Capture from Chrome Headless

Chrome Headless supports command-line screenshot and PDF capture. This is useful for a quick local capture without writing an automation script. The documented timeout setting determines when capture proceeds even if page content is still loading; a timeout alone does not prove asynchronous content is ready. [Chrome Headless command-line reference]

# Screenshot image
chrome --headless --screenshot=page.png --window-size=1280,900 https://example.com

# Print-layout PDF
chrome --headless --print-to-pdf=page.pdf https://example.com

Chrome’s command-line PDF operation uses the page’s print layout. For a repeatable custom physical paper size and controlled margins, use an automation API such as Playwright’s page.pdf(), where dimensions are explicit. Inspect the output to confirm that the site’s print styles and content readiness match the report.

6. Choose image or PDF for the final report

  • Choose a raster image when the report needs one visual, chart, or faithful screen view embedded in another document.
  • Choose PDF when paper dimensions, pagination, selectable text, or printing matter.
  • Choose an element capture to avoid surrounding navigation or unrelated page content.
  • Choose full-page capture when the entire scrollable layout must remain a single image; this can create a very tall file.

These outputs solve different problems. You cannot assign physical paper dimensions to a PNG with the browser’s PDF paper-size settings. You can place and scale that PNG in a report later, but the report’s layout then determines its printed size.

7. Use cURL, Python, or Node.js with ScreenshotNeo

If the deliverable is a website screenshot image, you can call ScreenshotNeo, a screenshot API and MCP server for developers. Its API returns an image or PDF from one GET request. For custom paper dimensions and print layout, use the browser PDF workflow above; the ScreenshotNeo request below is the one-call screenshot route. See the ScreenshotNeo API documentation for parameters and options.

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

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"},
    timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
await Bun.write('shot.webp', res);

In Node.js versions with global fetch, the request code above is runnable with Bun’s file helper; in plain Node.js, save the response with a writable stream or use this complete variant:

import { createWriteStream } from 'node:fs';
import { Readable } from 'node:stream';
import { pipeline } from 'node:stream/promises';

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok || !res.body) throw new Error(`Screenshot request failed: ${res.status}`);
await pipeline(Readable.fromWeb(res.body), createWriteStream('shot.webp'));

ScreenshotNeo supports full-page capture, element selection, viewport and device presets, retina scale, PDF settings including paper size and margins, wait conditions, custom CSS and JavaScript, headers and cookies, caching, and more. Only clean shots are billed; bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing. Responses include X-Page-Verdict and X-Billed headers. Its MCP server offers take_screenshot, get_page_info, and capture_pdf tools for AI agents. Plans include 1,000 monthly screenshots free with no card; paid plans start at $5 for 3,000, and every feature is available on every plan.

8. Troubleshooting

Symptom Likely cause What to do
PDF has the wrong page size CSS @page takes priority, or a named format and explicit dimensions conflict. Set preferCSSPageSize deliberately. Keep the page size in either CSS or the API and inspect the produced PDF.
Content is clipped or shrunk Content exceeds the printable area or is scaled to fit the paper. Adjust paper dimensions and margins, review print CSS, and check page breaks and wide elements.
Background colors are missing Print background graphics are not enabled or the site’s print CSS removes them. Set printBackground: true and inspect print-specific styles.
Charts or images are blank Capture ran before client rendering or image loading completed. Wait for a meaningful selector or application-ready signal, then capture again.
Screenshot cuts off content Only the viewport was captured. Use full-page capture for a tall image, or PDF output for paginated paper.
PDF differs from the browser view PDF uses print media, so print rules can hide, resize, or reflow content. Review the page’s @media print and @page CSS and inspect the PDF itself.
Capture times out Navigation or readiness condition did not complete within the timeout. Check the URL and network access, increase the timeout only when justified, and wait on a specific page condition where possible.
Full-page image is huge The page is very tall or uses a high device scale factor. Capture a relevant element, reduce viewport/device scale, or use a PDF when pagination is acceptable.

9. Performance, reliability, and cost

Browser capture cost is primarily the time and resources needed to start the browser, load the site, render assets, and write the output. Reuse a browser process for batches and create a fresh page per independent capture; limit parallel pages to avoid exhausting memory. Full-page and high-scale images need more memory than viewport images. PDFs can involve layout and pagination work across the document.

For reliability, use explicit timeouts, wait on content that matters, close pages and browsers in cleanup code, and retain the generated artifact long enough to inspect it. A fixed delay is simple but can waste time or still capture too early. Site access controls, transient network failures, changing content, and print styles can all affect the result. Retry transient navigation failures with a bounded retry policy; do not repeatedly retry a stable access denial.

Playwright and Chrome are software workflows rather than per-capture services in these examples; infrastructure and browser runtime determine their operating cost. ScreenshotNeo pricing is 1,000 shots per month free with no card, then Starter $5 for 3,000, Growth $15 for 15,000, Pro $39 for 60,000, Scale $99 for 250,000, and Business $249 for 1,000,000. Yearly billing gives two months free. Its billing rules mean bot checks, blank pages, timeouts, failed loads, and cache hits cost nothing; check the response billing headers for the outcome.

10. Or skip the browser setup

Use ScreenshotNeo’s API for a one-call website screenshot:

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

Cookie banners, popups, and chat widgets are removed before the shot. Bot checks, blank pages, and failed loads are never billed. An MCP server lets AI agents take screenshots. You get 1,000 screenshots a month free with no card, and paid plans start at $5 for 3,000. For reports that require custom paper dimensions, use the PDF options in the API documentation or the Playwright PDF workflow above.

Sign up free for 1,000 screenshots a month, with no card.

11. FAQ

Can a PNG have a custom paper size?

A PNG has pixel dimensions, not a PDF page size. Set its placement and print dimensions in the report or document that contains it.

Does a full-page screenshot create a multi-page report?

No. It creates a tall image. Use PDF printing when you need pages on defined paper.

Which unit should I use for custom paper?

Use millimeters or inches when dimensions come from a physical report specification. Playwright also accepts centimeters and pixels.

Why should I inspect the PDF after capture?

Print CSS, pagination, page breaks, margins, and content readiness can change the result. The rendered PDF is the artifact your report will use.