> ## 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.

# PDFs

With Browserbase, you can work with PDFs in a few ways:

1. **Generate**: Create PDFs from web pages with Playwright's `page.pdf()` method.
2. **Download**: Auto-download PDFs to Browserbase's cloud storage by opening a PDF URL. To retrieve them, see the [Downloads documentation](/platform/browser/files/downloads).
3. **View**: Display PDFs in the browser, instead of downloading them, by setting the `enablePdfViewer` property in your browser settings.

## Generate PDFs

After [creating and connecting to a session](/platform/browser/getting-started/using-browser-session), here's how to generate a PDF from a web page using Playwright:

<Tabs>
  <Tab title="Node.js">
    ```typescript Playwright theme={null}
    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://news.ycombinator.com");

      console.log("Generating PDF...");

      await page.pdf({
        path: "webpage.pdf",
        format: "A4",
      });

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

## Download PDFs

When you navigate to a PDF URL, Browserbase automatically downloads the PDF and cancels the navigation. Browserbase stores the file in cloud storage for later retrieval.

<Tabs>
  <Tab title="Node.js">
    <CodeGroup>
      ```typescript Playwright theme={null}
      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];

        // Configure download behavior
        const client = await defaultContext.newCDPSession(page);
        await client.send("Browser.setDownloadBehavior", {
          behavior: "allow",
          downloadPath: "downloads",
          eventsEnabled: true,
        });

        // Navigate to PDF and trigger download
        console.log("Attempting to download PDF...");
        const [download] = await Promise.all([
          page.waitForEvent("download"),
          page.goto("https://constitutioncenter.org/media/files/constitution.pdf").catch(() => {
            console.log("Navigation cancelled due to download (expected behavior)");
          })
        ]);

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

        console.log("PDF download completed successfully");

        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 { 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];

        // Configure download behavior
        const client = await page.createCDPSession();
        await client.send("Browser.setDownloadBehavior", {
          behavior: "allow",
          downloadPath: "downloads",
          eventsEnabled: true,
        });

        console.log("Attempting to download PDF...");

        // Navigate to PDF URL
        await page.goto("https://constitutioncenter.org/media/files/constitution.pdf").catch(() => {
          console.log("Navigation cancelled due to download (expected behavior)");
        });

        // Wait a moment for download to complete
        await new Promise(resolve => setTimeout(resolve, 3000));

        console.log("PDF download completed successfully");

        console.log("Shutting down...");
        await page.close();
        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
      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]

          # Configure download behavior
          client = context.new_cdp_session(page)
          client.send("Browser.setDownloadBehavior", {
              "behavior": "allow",
              "downloadPath": "downloads",
              "eventsEnabled": True,
          })

          print("Attempting to download PDF...")

          # Set up download handling and navigate to PDF
          with page.expect_download() as download_info:
              try:
                  page.goto("https://constitutioncenter.org/media/files/constitution.pdf")
              except Exception:
                  print("Navigation cancelled due to download (expected behavior)")

          download = download_info.value

          # Check for download errors
          if download.failure():
              print(f"Error happened on download: {download.failure()}")
              raise Exception(download.failure())

          print("PDF download completed successfully")

          print("Shutting down...")
          page.close()
          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
      import time
      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)

          # Configure Chrome options for downloads
          options = webdriver.ChromeOptions()
          prefs = {
              "download.default_directory": "downloads",
              "download.prompt_for_download": False,
              "plugins.always_open_pdf_externally": True
          }
          options.add_experimental_option("prefs", prefs)

          driver = webdriver.Remote(custom_conn, options=options)

          print("Attempting to download PDF...")

          # Navigate to PDF URL
          driver.get("https://constitutioncenter.org/media/files/constitution.pdf")

          # Wait for download to complete
          time.sleep(5)

          print("PDF download completed successfully")

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

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

Retrieve the downloaded PDF from Browserbase's cloud storage. See [Downloads](/platform/browser/files/downloads) for details on accessing your files.

<Callout icon="code" color="#6ec202" iconType="regular">View or run the example template [here](https://www.browserbase.com/templates/download-financial-statements)</Callout>

## View PDFs

To view a PDF in the browser tab instead of downloading it, set `enablePdfViewer` to `true`:

<Tabs>
  <Tab title="Node.js">
    <CodeGroup>
      ```ts SDK theme={null}
      const bb = new Browserbase({ apiKey: process.env.BROWSERBASE_API_KEY });
      const session = await bb.sessions.create({
        browserSettings: {
          enablePdfViewer: true,
        },
      });
      ```
    </CodeGroup>
  </Tab>

  <Tab title="Python">
    <CodeGroup>
      ```python SDK theme={null}
      bb = Browserbase(api_key=os.environ["BROWSERBASE_API_KEY"])
      session = bb.sessions.create(
        browser_settings={
            "enablePdfViewer": True,
        },
      )
      ```
    </CodeGroup>
  </Tab>
</Tabs>
