Taking screenshots

Browserbase enables screen view and full-screen screenshots using your desired browser automation framework with the following configuration:

Screenshot typeDPIFormat
Screen view (default)80jpeg
Full-screen90jpeg

Save a screenshot locally

A Screenshot taken with Browserbase can be saved locally as a file:

import { writeFileSync } from "fs";
import { chromium } from "playwright-core";

(async () => {
  console.log("Starting remote browser...")
  const browser = await chromium.connectOverCDP(
      // we connect to a Session created via the API
      `wss://connect.browserbase.com?apiKey=${process.env.BROWSERBASE_API_KEY}&sessionId=${sessionId}`,
  );
  const defaultContext = browser.contexts()[0];
  const page = defaultContext.pages()[0];

  await page.goto("https://www.browserbase.com", {
      // let's make sure the page is fully loaded before taking the screenshot
      waitUntil: "domcontentloaded",
  });

  console.log("Taking a screenshot!")

  const buf = await page.screenshot({ fullPage: true })
  writeFileSync('screenshot.jpeg', buf)

  console.log("Shutting down...")
  await page.close();
  await browser.close();
})().catch((error) => {
    console.error(error)
}

Downloading files

A typical use-case for using headless browsers includes downloading files from web pages. Our browsers are configured to sync any file you download to our storage infrastructure.

Follow the steps to download files:

  1. Use the Create Session API to create a new session. You’ll need the session ID for when you connect.

  2. Finally, configure your library’s downloads location:

import { chromium } from "playwright-core";
import { writeFileSync } from "node:fs";

async function saveDownloadsOnDisk(sessionId: string, retryForSeconds: number) {
  return new Promise<void>((resolve, reject) => {
    let pooler;
    const timeout = setTimeout(() => {
      if (pooler) {
        clearInterval(pooler);
      }
    }, retryForSeconds);
    async function fetchDownloads() {
      try {
        const response = await fetch(
          `https://www.browserbase.com/v1/sessions/${sessionId}/downloads`,
          {
            method: "GET",
            headers: {
              "x-bb-api-key": process.env.BROWSERBASE_API_KEY!,
            },
          },
        );
        const arrayBuffer = await response.arrayBuffer();
        if (arrayBuffer.byteLength > 0) {
          const buffer = Buffer.from(arrayBuffer);
          writeFileSync("downloads.zip", buffer);
          clearInterval(pooler);
          clearTimeout(timeout);
          resolve();
        }
      } catch (e) {
        clearInterval(pooler);
        clearTimeout(timeout);
        reject(e);
      }
    }
    pooler = setInterval(fetchDownloads, 2000);
  });
}

(async () => {
  // `createSession()` performs a call to the Browserbase Session API
  const { id: sessionId } = await createSession();
  const browser = await chromium.connectOverCDP(
    // we connect to a Session created via the API
    `wss://connect.browserbase.com?apiKey=${process.env.BROWSERBASE_API_KEY}&sessionId=${sessionId}`,
  );
  const defaultContext = browser.contexts()[0];
  const page = defaultContext.pages()[0];

  // Required to avoid playwright overriding location
  const client = await defaultContext.newCDPSession(page);
  await client.send("Page.setDownloadBehavior", {
    behavior: "allow",
    downloadPath: "downloads",
    //@ts-ignore
    eventsEnabled: true,
  });

  await page.goto("https://browser-tests-alpha.vercel.app/api/download-test");

  const [download] = await Promise.all([
    page.waitForEvent("download"),
    page.locator("#download").click(),
  ]);

  let downloadError = await download.failure();
  if (downloadError !== null) {
    console.log("Error happened on download:", downloadError);
    throw new Error(downloadError);
  }

  await page.close();
  await browser.close();

  if (!downloadError) {
    // wait up to 20s to save the downloaded files locally
    await saveDownloadsOnDisk(sessionId, 20000);
  }
})().catch((error) => console.error(error.message));

We sync the files in real time; the size of your downloads might affect their immediate availability through the /downloads endpoint. The above code provides a snippet to handle that use case.

Session downloads API

Learn more on the available params and response fields