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.
- A Browserless API token from your account dashboard
- The BAP SDK installed and connecting, from the BAP Quickstart
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.
- TypeScript
- Python
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();
}
import bap.sync_api as bap
TOKEN = "YOUR_API_TOKEN_HERE"
with bap.Browserless.connect(
browser_ws_endpoint="wss://production-sfo.browserless.io/chromium/bql",
token=TOKEN,
) as browser:
with browser.page() as page:
page.goto("https://example.com")
# Returns bytes. `path` also writes to disk.
page.screenshot(path="screenshot.png")
# Full page, in a smaller format.
page.screenshot(
path="full.webp",
type="webp",
full_page=True,
quality=80,
)
Screenshot options
| Option | Default | What it does |
|---|---|---|
type | png | Output format. quality applies to everything except PNG |
fullPage | false | Capture the entire scroll height instead of the viewport |
selector | — | Capture one element instead of the page |
clip | — | Capture a specific region, given x, y, width, and height |
quality | — | Compression quality from 0 to 100. Ignored for PNG |
omitBackground | false | Drop the default white background so transparency survives |
waitForImages | false | Wait for every image to load first, which is what you want on image-heavy pages |
captureBeyondViewport | varies | Defaults 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:
- TypeScript
- Python
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" });
page.set_viewport_size(width=1920, height=1080)
page.goto("https://example.com")
# One element, not the whole page.
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.
- TypeScript
- Python
await page.goto("https://example.com/invoice");
await page.pdf({
path: "invoice.pdf",
format: "a4",
printBackground: true,
marginTop: "1in",
waitForFonts: true,
});
page.goto("https://example.com/invoice")
page.pdf(
path="invoice.pdf",
format="a4",
print_background=True,
margin_top="1in",
wait_for_fonts=True,
)
PDF options worth knowing
| Option | Default | What it does |
|---|---|---|
format | — | Page size such as a4 or letter. Use width/height for a custom size |
printBackground | false | Include background graphics, which most page designs need |
landscape | false | Paper orientation |
fullPage | false | Size the page height to the full document so everything lands on one page |
marginTop, marginRight, marginBottom, marginLeft | ~1cm | Margins, in inches or any CSS unit |
pageRanges | — | Print a subset, such as "1-5, 8" |
displayHeaderFooter + headerTemplate / footerTemplate | false | Inject HTML headers and footers |
preferCSSPageSize | false | Let the page's own CSS @page size win over format |
waitForFonts, waitForImages | false | Wait for fonts or images before rendering |
generateTaggedPDF | varies | Emit a tagged, accessible PDF |
To render the screen layout rather than the print stylesheet, switch the media type first:
- TypeScript
- Python
// Render what the screen shows, ignoring print CSS.
await page.emulateMediaType("screen");
await page.pdf({ path: "screen.pdf", printBackground: true });
# Render what the screen shows, ignoring print CSS.
page.emulate_media(type="screen")
page.pdf(path="screen.pdf", print_background=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.