> ## Documentation Index
> Fetch the complete documentation index at: https://docs.browserbase.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Screenshots

Browserbase supports viewport and full-page screenshots with any browser automation framework. For best performance, use [CDP (Chrome DevTools Protocol)](https://chromedevtools.github.io/devtools-protocol/tot/Page/#method-captureScreenshot) to capture screenshots — it's significantly faster than standard approaches.

## Take a screenshot

First, [create a browser session](/platform/browser/getting-started/create-browser-session) and [connect to it](/platform/browser/getting-started/using-browser-session). Then take a screenshot using CDP for best performance:

<Tabs>
  <Tab title="Node.js">
    <CodeGroup>
      ```typescript Playwright theme={null}
      import { writeFileSync } from "fs";
      import { chromium } from "playwright-core";
      import { Browserbase } from "@browserbasehq/sdk";

      (async () => {
        console.log("Starting remote browser...");
        const bb = new Browserbase({ apiKey: process.env.BROWSERBASE_API_KEY });
        const session = await bb.sessions.create();

        const browser = await chromium.connectOverCDP(session.connectUrl);
        const defaultContext = browser.contexts()[0];
        const page = defaultContext.pages()[0];

        await page.goto("https://www.nationalgeographic.com/");

        console.log("Taking a screenshot using CDP...");

        // Create a CDP session for faster screenshots
        const client = await defaultContext.newCDPSession(page);

        // Capture a full-page screenshot using CDP
        const { data } = await client.send("Page.captureScreenshot", {
          format: "jpeg",
          quality: 80,
          captureBeyondViewport: true,
        });

        // Convert base64 to buffer and save
        const buffer = Buffer.from(data, "base64");
        writeFileSync("screenshot.jpeg", buffer);

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

      ```typescript Puppeteer theme={null}
      import puppeteer from "puppeteer-core";
      import fs from "fs";
      import { Browserbase } from "@browserbasehq/sdk";

      (async () => {
        console.log("Starting remote browser...");
        const bb = new Browserbase({ apiKey: process.env.BROWSERBASE_API_KEY });
        const session = await bb.sessions.create();

        const browser = await puppeteer.connect({
          browserWSEndpoint: session.connectUrl,
        });
        const pages = await browser.pages();
        const page = pages[0];

        await page.goto("https://www.nationalgeographic.com/");

        console.log("Taking a screenshot using CDP...");

        // Create a CDP session for faster screenshots
        const client = await page.createCDPSession();

        // Capture a full-page screenshot using CDP
        const { data } = await client.send("Page.captureScreenshot", {
          format: "jpeg",
          quality: 80,
          captureBeyondViewport: true,
        });

        // Convert base64 to buffer and save
        const buffer = Buffer.from(data, "base64");
        fs.writeFileSync("screenshot.jpeg", buffer);

        console.log("Shutting down...");
        await browser.close();
      })().catch((error) => {
        console.error(error);
      });
      ```
    </CodeGroup>
  </Tab>

  <Tab title="Python">
    <CodeGroup>
      ```python Playwright theme={null}
      from playwright.sync_api import sync_playwright, Playwright
      import os
      import base64
      from browserbase import Browserbase

      def main(p: Playwright):
          print("Starting remote browser...")
          bb = Browserbase(api_key=os.environ["BROWSERBASE_API_KEY"])
          session = bb.sessions.create()

          browser = p.chromium.connect_over_cdp(session.connect_url)
          context = browser.contexts[0]
          page = context.pages[0]

          page.goto("https://www.nationalgeographic.com/")

          print("Taking a screenshot using CDP!")

          # Create a CDP session for faster screenshots
          client = context.new_cdp_session(page)

          # Capture a full-page screenshot using CDP
          screenshot_data = client.send("Page.captureScreenshot", {
              "format": "jpeg",
              "quality": 80,
              "captureBeyondViewport": True
          })

          # Convert base64 to bytes and save
          image_data = base64.b64decode(screenshot_data['data'])
          with open('screenshot.jpeg', 'wb') as f:
              f.write(image_data)

          print("Shutting down...")
          browser.close()

      with sync_playwright() as playwright:
          main(playwright)
      ```

      ```python Selenium theme={null}
      from selenium import webdriver
      from selenium.webdriver.remote.remote_connection import RemoteConnection
      import os
      from browserbase import Browserbase

      def run():
          bb = Browserbase(api_key=os.environ["BROWSERBASE_API_KEY"])
          session = bb.sessions.create()

          # Create a custom connection with the session details
          class CustomRemoteConnection(RemoteConnection):
              def get_remote_connection_headers(self, parsed_url, keep_alive=False):
                  headers = super().get_remote_connection_headers(parsed_url, keep_alive)
                  headers["x-bb-api-key"] = os.environ["BROWSERBASE_API_KEY"]
                  headers["session-id"] = session.id
                  return headers

          custom_conn = CustomRemoteConnection(session.selenium_remote_url)
          options = webdriver.ChromeOptions()
          driver = webdriver.Remote(custom_conn, options=options)

          driver.get("https://www.nationalgeographic.com/")

          print("Taking a screenshot...")

          # Take screenshot using Selenium's built-in method
          driver.save_screenshot('screenshot.png')

          # Make sure to quit the driver so your session is ended!
          driver.quit()

      run()
      ```
    </CodeGroup>
  </Tab>
</Tabs>

<Note>
  For a **viewport-only screenshot** (just what's visible on screen) with CDP, remove `captureBeyondViewport` or set it to `false`.
</Note>

### CDP screenshot reference

Just the CDP screenshot code:

<Tabs>
  <Tab title="Node.js">
    <CodeGroup>
      ```typescript Playwright theme={null}
      // Create CDP session
      const client = await defaultContext.newCDPSession(page);

      // Capture screenshot
      const { data } = await client.send("Page.captureScreenshot", {
        format: "jpeg",
        quality: 80,
        captureBeyondViewport: true,
      });

      // Save
      const buffer = Buffer.from(data, "base64");
      writeFileSync("screenshot.jpeg", buffer);
      ```

      ```typescript Puppeteer theme={null}
      // Create CDP session
      const client = await page.createCDPSession();

      // Capture screenshot
      const { data } = await client.send("Page.captureScreenshot", {
        format: "jpeg",
        quality: 80,
        captureBeyondViewport: true,
      });

      // Save
      const buffer = Buffer.from(data, "base64");
      fs.writeFileSync("screenshot.jpeg", buffer);
      ```
    </CodeGroup>
  </Tab>

  <Tab title="Python">
    ```python Playwright theme={null}
    # Create CDP session
    client = context.new_cdp_session(page)

    # Capture screenshot
    screenshot_data = client.send("Page.captureScreenshot", {
        "format": "jpeg",
        "quality": 80,
        "captureBeyondViewport": True
    })

    # Save
    image_data = base64.b64decode(screenshot_data['data'])
    with open('screenshot.jpeg', 'wb') as f:
        f.write(image_data)
    ```
  </Tab>
</Tabs>

## Why use CDP for screenshots?

[CDP (Chrome DevTools Protocol)](https://chromedevtools.github.io/devtools-protocol/tot/Page/#method-captureScreenshot) offers several advantages for screenshots:

1. **Performance**: CDP screenshots are significantly faster than traditional methods
2. **Memory efficiency**: Uses less memory as it directly communicates with the browser's debugging protocol
3. **Quality control**: Provides more control over image quality and format settings
4. **Reliability**: More stable for full-page screenshots of complex web applications

For most use cases, the CDP approach shown above outperforms standard screenshot methods.
