For AI agents: a documentation index is available at /llms.txt
Skip to main content

Screenshots and PDFs with BAP

screenshot() and pdf() both render the current page and hand back bytes. This guide covers capturing a full page or a single element, choosing a format, and the wait options that decide whether images and fonts have loaded before the capture happens.

Prerequisites

Capture a screenshot

Both methods return the image bytes. The path option additionally writes to disk, which works in Node.js and Python but rejects in the browser build, where you use the returned bytes instead.

import Browserless from "@browserless.io/bap-ts";

const TOKEN = "YOUR_API_TOKEN_HERE";

const browser = Browserless.connect({
browserWSEndpoint: "wss://production-sfo.browserless.io/chromium/bql",
token: TOKEN,
});

try {
const page = await browser.newPage();
await page.goto("https://example.com");

// Returns a Uint8Array. `path` also writes to disk, and is Node.js only.
await page.screenshot({ path: "screenshot.png" });

// Full page, in a smaller format.
await page.screenshot({
path: "full.webp",
type: "webp",
fullPage: true,
quality: 80,
});
} finally {
await browser.close();
}

Screenshot options

OptionDefaultWhat it does
typepngOutput format. quality applies to everything except PNG
fullPagefalseCapture the entire scroll height instead of the viewport
selectorCapture one element instead of the page
clipCapture a specific region, given x, y, width, and height
qualityCompression quality from 0 to 100. Ignored for PNG
omitBackgroundfalseDrop the default white background so transparency survives
waitForImagesfalseWait for every image to load first, which is what you want on image-heavy pages
captureBeyondViewportvariesDefaults to false with a clip, true otherwise

Set the viewport before capturing when the layout is responsive, since the screenshot reflects whatever width the page was rendered at:

await page.setViewport({ width: 1920, height: 1080 });
await page.goto("https://example.com");

// One element, not the whole page.
await page.screenshot({ selector: "#pricing-table", path: "pricing.png" });

Generate a PDF

pdf() renders through Chrome's print pipeline, so it honors print stylesheets rather than the screen layout. That's why printBackground exists: browsers drop background graphics when printing, and a page that looks right on screen comes out white without it.

await page.goto("https://example.com/invoice");

await page.pdf({
path: "invoice.pdf",
format: "a4",
printBackground: true,
marginTop: "1in",
waitForFonts: true,
});

PDF options worth knowing

OptionDefaultWhat it does
formatPage size such as a4 or letter. Use width/height for a custom size
printBackgroundfalseInclude background graphics, which most page designs need
landscapefalsePaper orientation
fullPagefalseSize the page height to the full document so everything lands on one page
marginTop, marginRight, marginBottom, marginLeft~1cmMargins, in inches or any CSS unit
pageRangesPrint a subset, such as "1-5, 8"
displayHeaderFooter + headerTemplate / footerTemplatefalseInject HTML headers and footers
preferCSSPageSizefalseLet the page's own CSS @page size win over format
waitForFonts, waitForImagesfalseWait for fonts or images before rendering
generateTaggedPDFvariesEmit a tagged, accessible PDF

To render the screen layout rather than the print stylesheet, switch the media type first:

// Render what the screen shows, ignoring print CSS.
await page.emulateMediaType("screen");
await page.pdf({ path: "screen.pdf", printBackground: true });

FAQ & Troubleshooting

My screenshot is missing images that appear in a browser

The capture happened before the images finished loading. Pass waitForImages: true, or wait for a specific element with waitForSelector() first. Lazy-loaded images below the fold also need scroll({ throughPage: true }) to trigger their loading.

The PDF came out white with no styling

Set printBackground: true. Browsers omit background colors and images when printing, so the default output drops most of a page's design. If the print stylesheet itself is the problem, call emulateMediaType("screen") before pdf().

Why does quality have no effect?

quality doesn't apply to PNG, which is lossless. Switch type to jpeg or webp to use it.

(Browser build) path rejects instead of saving the file

Writing to disk is a Node.js and Python capability. In the browser build, take the returned Uint8Array and turn it into a Blob for display or download. See the Quickstart's runtime notes.

Next steps

Was this page helpful?