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

# Session live view

> An interactive window to display or control a browser session.

On any running browser session - watch, click, type, and scroll in real-time.

<Frame>
  <video src="https://mintcdn.com/browserbase/Qn5OB0mYcUstQ-qY/images/live-view/live-view.mp4?fit=max&auto=format&n=Qn5OB0mYcUstQ-qY&q=85&s=11903d1a98d32bcea4c9dabc7538906e" alt="Session Live View" loop autoPlay muted controls data-path="images/live-view/live-view.mp4" />
</Frame>

***

## Uses

While Browserbase helps with [bot protection systems](/platform/identity/overview),
data extraction, and [reliable file downloads](/platform/browser/files/downloads), some scenarios
remain challenging to fully automate for technical or data-privacy reasons.

Live Views can be useful for:

* Debugging and observability - watch everything happening live, or share with users or coworkers
* Human in the loop - instantly take control or provide input
  * handle iframes - loaded content might be external or change without notice, causing errors without human intervention
  * delegate credentials - give control to the end user
  * upload files - see the [uploads guide](/platform/browser/files/uploads#manual-upload-through-live-view) to enable uploads through the live view
* Embedding - use within an application (both desktop and mobile)

***

## Getting started

<Note>
  Need help getting started? Check out the [Create a Browser Session](/platform/browser/getting-started/create-browser-session) and [Using Browser Sessions](/platform/browser/getting-started/using-browser-session) guides.
</Note>

Also check out the [Live Views API endpoint](/reference/api/session-live-urls).

<CodeGroup>
  ```typescript Node.js theme={null}
  const liveViewLinks = await bb.sessions.debug(session.id);
  const liveViewLink = liveViewLinks.debuggerFullscreenUrl;
  console.log(`Live View Link: ${liveViewLink}`);

  // [Optional] If you want to automatically open up the live view URL in your browser tab, you can also run the lines below:
  import open from 'open';
  open(liveViewLink);
  ```

  ```python Python theme={null}
  live_view_links = bb.sessions.debug(session.id)
  live_view_link = live_view_links.debuggerFullscreenUrl
  print(f"Live View Link: {live_view_link}")

  # [Optional] If you want to automatically open up the live view URL in your browser tab, you can also run the lines below:
  import webbrowser
  webbrowser.open(live_view_link)
  ```
</CodeGroup>

***

## Multitab

Each tab has a unique live view url.

The `pages` property contains all live view urls.

Listen for the [Playwright new tab event](https://playwright.dev/docs/pages#handling-new-pages) (or equivalent in other libraries) to fetch new live view urls as tabs open.

<CodeGroup>
  ```typescript Node.js theme={null}
  // Open a new tab and navigate to google
  const newTab = await defaultContext.newPage();
  newTab.goto("https://www.google.com");

  // Get the live view links after the new tab is opened - then access the second tab
  const liveViewLinks = await bb.sessions.debug(session.id);
  const allTabs = liveViewLinks.pages;
  const secondTabLiveViewLink = allTabs[1].debuggerFullscreenUrl;
  console.log(`Second Tab Live View Link: ${secondTabLiveViewLink}`);
  ```

  ```python Python theme={null}
  # Open a new tab and navigate to google
  new_tab = await default_context.new_page()
  new_tab.goto("https://www.google.com")

  # Get the live view links after the new tab is opened - then access the second tab
  live_view_links = bb.sessions.debug(session.id)
  all_tabs = live_view_links.pages
  second_tab_live_view_link = all_tabs[1].debuggerFullscreenUrl
  print(f"Second Tab Live View Link: {second_tab_live_view_link}")
  ```
</CodeGroup>

***

## Embedding

Add the live view link to an iframe in your frontend to embed it.

<CodeGroup>
  ```html Read-only theme={null}
  <iframe
    src="{liveViewLink}"
    sandbox="allow-same-origin allow-scripts"
    allow="clipboard-read; clipboard-write"
    style="pointer-events: none;"
  />
  ```

  ```html Read/Write theme={null}
  <iframe
    src="{liveViewLink}"
    sandbox="allow-same-origin allow-scripts"
    allow="clipboard-read; clipboard-write"
  />
  ```
</CodeGroup>

### Mobile

Show a mobile live view by setting a session's [viewport](/reference/api/create-a-session#body-browser-settings-viewport).

<CodeGroup>
  ```typescript Node.js theme={null}
  // Standard android mobile dimensions
  browserSettings: {
    viewport: {
      width: 360,
      height: 800,
    },
  },
  // ...other session configuration options
  ```

  ```python Python theme={null}
  # Standard android mobile dimensions
  browser_settings={
    "viewport": {
      "width": 360,
      "height": 800
    }
  },
  # ...other session configuration options
  ```
</CodeGroup>

To display a keyboard with a mobile live view, use a library like [react-simple-keyboard](https://www.npmjs.com/package/react-simple-keyboard).

<Note>
  Mobile keyboards aren't officially supported. Desktop works natively, but for mobile you'll need to handle key events and send them to your automation script (like via HTTP or WebSocket). Once there, call `page.keyboard.press()` to forward them into the session.

  Some virtual keyboard keys need to be mapped to your framework's key names (e.g. `{ent}` → `"Enter"`). You may need to override keys like Tab so they're sent to the session and not processed by the local browser.
</Note>

### Handling disconnects

When the browser session ends, the live view will show a disconnect message:

<Frame>
  <img src="https://mintcdn.com/browserbase/m1Ny8qOvNHvtrY7y/images/live-view/disconnect.png?fit=max&auto=format&n=m1Ny8qOvNHvtrY7y&q=85&s=c5426f0ee027ad6664f8824183022ccf" alt="Live View Disconnect Message" width="2242" height="1800" data-path="images/live-view/disconnect.png" />
</Frame>

You can listen for this event programmatically:

```javascript theme={null}
window.addEventListener("message", function (event) {
  if (event.data === "browserbase-disconnected") {
    // Handle the disconnection (e.g., show a message, clean up resources)
    console.log("Live view disconnected");
  }
});
```

***

## Styling

### Browser with borders

Mimic a real browser with borders.

<Frame>
  <img src="https://mintcdn.com/browserbase/m1Ny8qOvNHvtrY7y/images/live-view/with-border.png?fit=max&auto=format&n=m1Ny8qOvNHvtrY7y&q=85&s=5eb36d6662b9c3424f95ba6079e4eecc" alt="Session Live View with Borders" width="3024" height="1886" data-path="images/live-view/with-border.png" />
</Frame>

<CodeGroup>
  ```typescript Node.js theme={null}
  const liveViewLinks = await bb.sessions.debug(session.id);
  const liveViewLink = liveViewLinks.debuggerUrl;
  console.log(`Live View Link - with borders: ${liveViewLink}`);
  ```

  ```python Python theme={null}
  live_view_links = bb.sessions.debug(session.id)
  live_view_link = live_view_links.debuggerUrl
  print(f"Live View Link - with borders: {live_view_link}")
  ```
</CodeGroup>

### Hide the navbar

The live view includes a navbar at the top for context and navigation.

Hide it to maximize the visible area or when your UI already provides context.

<CodeGroup>
  ```typescript Node.js theme={null}
  const hiddenNavbarUrl = `${liveViewLink}&navbar=false`;
  ```

  ```python Python theme={null}
  hidden_navbar_url = f"{live_view_link}&navbar=false"
  ```
</CodeGroup>

### Hide the scrollbar

<Tabs>
  <Tab title="JavaScript">
    <CodeGroup>
      ```typescript Playwright/Puppeteer theme={null}
      // Navigate to the page
      await page.goto("https://news.ycombinator.com/");

      // Hide the scrollbar
      await page.evaluate(() => {
        const style = document.createElement("style");
        style.textContent = `::-webkit-scrollbar { display: none; }`;
        document.head.appendChild(style);
      });
      ```

      ```typescript Selenium theme={null}
      // Navigate to the page
      await driver.get("https://news.ycombinator.com/");

      // Hide the scrollbar
      await driver.executeScript(`
      	const style = document.createElement("style");
      	style.textContent = "::-webkit-scrollbar { display: none; }";
      	document.head.appendChild(style);
      `);
      ```
    </CodeGroup>
  </Tab>

  <Tab title="Python">
    <CodeGroup>
      ```python Playwright theme={null}
      # Navigate to the page
      page.goto("https://www.browserbase.com")

      # Hide the scrollbar
      page.evaluate("""
        const style = document.createElement('style');
        style.textContent = '::-webkit-scrollbar { display: none; }';
        document.head.appendChild(style);
      """)
      ```

      ```python Selenium theme={null}
      # Navigate to the page
      driver.get("https://www.browserbase.org")

      # Hide the scrollbar
      driver.execute_script("""
        style = document.createElement("style");
        style.textContent = "::-webkit-scrollbar { display: none; }";
        document.head.appendChild(style);
      """)
      ```
    </CodeGroup>
  </Tab>
</Tabs>

***

## Troubleshooting

1. **Blank or empty window**

   You may be on another tab. Check if there are multiple tabs open via [the web session inspector](/platform/browser/observability/observability) or [the pages list](#multitab).

2. **Lag**

   Check out the [performance guide](/optimizations/latency/speed-optimization).

3. **Looks off**

   Often caused by headless browser rendering differences. Some issues may be fixable by adjusting CSS styling through `page.evaluate()`.

4. **Lost Connection**

   If the live view loses its connection to the browser, the iframe will post a `browserbase-disconnected` message. See [Handling Disconnects](#handling-disconnects) for how to listen for this event.
