Screenshot Best Practices
Capture stable, reproducible browser screenshots across headless and headful environments.
Prerequisites
- BotBrowser installed and running. See Installation Guide.
- A profile file (
.encfor production). - Playwright or Puppeteer installed for programmatic screenshots.
- On Linux: A virtual display (Xvfb) must be running. See Headless Server Setup.
Quick Start
Playwright
import { chromium } from "playwright-core";
const browser = await chromium.launch({
executablePath: process.env.BOTBROWSER_EXEC_PATH,
headless: true,
args: [
`--bot-profile=${process.env.BOT_PROFILE_PATH}`,
],
});
const page = await browser.newPage();
await page.goto("https://example.com");
// Viewport screenshot
await page.screenshot({ path: "viewport.png" });
// Full page screenshot
await page.screenshot({ path: "fullpage.png", fullPage: true });
await browser.close();Puppeteer
import puppeteer from "puppeteer-core";
const browser = await puppeteer.launch({
executablePath: process.env.BOTBROWSER_EXEC_PATH,
headless: true,
defaultViewport: null,
args: [
`--bot-profile=${process.env.BOT_PROFILE_PATH}`,
],
});
const page = await browser.newPage();
await page.goto("https://example.com");
// Viewport screenshot
await page.screenshot({ path: "viewport.png" });
// Full page screenshot
await page.screenshot({ path: "fullpage.png", fullPage: true });
await browser.close();How It Works
Screenshots in BotBrowser use the same rendering pipeline as a regular Chrome installation, with fingerprint properties applied from the profile:
-
Resolution and DPI. The profile defines screen dimensions and device pixel ratio (DPR). A profile with DPR 2 produces screenshots at 2x the viewport pixel dimensions. In Puppeteer, always set
defaultViewport: nullso Puppeteer does not override the profile’s display settings. In Playwright, do not set explicit viewport dimensions in context options. -
Viewport vs. full page. A viewport screenshot captures only the visible area. A full page screenshot scrolls the entire page and stitches the result. The viewport dimensions come from the profile.
-
Rendering consistency. Canvas noise, font rendering, and WebGL output are all determined by the profile. Screenshots taken with the same profile produce identical visual output across different host systems.
-
Headless Linux. On servers without a monitor, Xvfb provides the virtual display that Chrome’s compositor needs. Without it, screenshots time out or produce blank images.
Common Scenarios
Correct screenshot order
When taking both viewport and full page screenshots, capture the full page screenshot first or wait between captures. Taking a viewport screenshot immediately followed by a full page screenshot in rapid succession can cause rendering issues:
// Recommended: wait for the page to stabilize
await page.goto("https://example.com", { waitUntil: "networkidle" });
// Take viewport screenshot
await page.screenshot({ path: "viewport.png" });
// Wait briefly before full page capture
await page.waitForTimeout(500);
await page.screenshot({ path: "fullpage.png", fullPage: true });PNG vs. JPEG format
// PNG: lossless, larger files, better for text-heavy pages
await page.screenshot({ path: "output.png", type: "png" });
// JPEG: lossy, smaller files, configurable quality
await page.screenshot({ path: "output.jpg", type: "jpeg", quality: 80 });Use PNG when pixel accuracy matters (fingerprint verification, visual regression testing). Use JPEG for general-purpose captures where file size is a concern.
High-DPI screenshots
The screenshot resolution is determined by the profile’s device pixel ratio. A profile with devicePixelRatio: 2 on a 1920x1080 viewport produces a 3840x2160 screenshot:
// The profile controls DPI. No additional configuration needed.
await page.screenshot({ path: "hidpi.png" });To override the profile’s DPI for a specific use case:
chromium-browser \
--bot-profile="/path/to/profile.enc" \
--bot-config-disable-device-scale-factor=trueScreenshots on headless Linux
Ensure Xvfb is running with a resolution at least as large as the profile’s screen dimensions:
# Start Xvfb with sufficient resolution
Xvfb :10 -screen 0 2560x1440x24 -ac &
export DISPLAY=:10.0
# Launch BotBrowser
chromium-browser \
--headless \
--no-sandbox \
--bot-profile="/path/to/profile.enc" \
--remote-debugging-port=9222If the Xvfb resolution is smaller than the profile’s screen size, screenshots may be clipped or produce unexpected results.
Element-specific screenshots
// Playwright
const element = await page.locator("#target-element");
await element.screenshot({ path: "element.png" });
// Puppeteer
const element = await page.$("#target-element");
await element.screenshot({ path: "element.png" });Troubleshooting / FAQ
| Problem | Solution |
|---|---|
| Screenshot times out on Linux | Ensure Xvfb is running and DISPLAY=:10.0 is set. See Headless Server Setup. |
| Blank or all-white screenshot | The page may not have finished loading. Use waitUntil: "networkidle" or wait for a specific element. |
| Screenshot resolution is wrong | In Puppeteer, set defaultViewport: null to let the profile control dimensions. In Playwright, do not set explicit viewport options. |
| Full page screenshot crashes | Avoid capturing viewport and full page screenshots in rapid succession. Add a brief wait between them. |
| Fonts look different than expected | BotBrowser uses the profile’s embedded font bundle. Verify the profile matches your expected platform (Windows, macOS, etc.). |
| Colors appear different across runs | This is expected. Canvas noise produces deterministic but session-unique visual output. Use the same profile and noise seed for identical results. |
Next Steps
- Headless Server Setup. Configure Xvfb and system libraries for Linux.
- Performance Optimization. Optimize rendering speed for screenshot workloads.
- Playwright Guide. Full Playwright integration reference.
- CLI Flags Reference. Display and rendering override flags.
Related documentation: Advanced Features | Installation Guide
Legal Disclaimer & Terms of Use • Responsible Use Guidelines . BotBrowser is for authorized fingerprint protection and privacy research only.