> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.airtop.ai/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.airtop.ai/_mcp/server.

# Creating a Live View

## What is a Live View?

A live view is a way to provide real-time interactive access of your browser to your users. You can use a live view to support a range of use cases, including:

* Authentication workflows
* Human / AI training use cases
* Human in the loop workflows

## How to use a Live View

### Step 1

Once you have a session and have loaded a url in a window, you can request a live view URL from the API.

**`NodeJS`**

```typescript NodeJS
const windowInfo = await client.windows.getWindowInfo(session.data.id, windowId);
const liveViewUrl = windowInfo.data.liveViewUrl;
```

**`Python`**

```python Python
window_info = client.windows.get_window_info(session.data.id, window_id)
live_view_url = window_info.data.live_view_url
```

> **Note**
>
> If you're using Puppeteer, Playwright, or Selenium, you can use framework specific `getWindowInfo` variants.
>
> ```typescript NodeJS
> const windowInfo = await client.windows.getWindowInfoForPuppeteerPage(session.data, page); // page is a puppeteer.Page object
> const windowInfo = await client.windows.getWindowInfoForPlaywrightPage(session.data, page); // page is a playwright.Page object
> const windowInfo = await client.windows.getWindowInfoForSeleniumDriver(session.data, driver); // driver is a seleniumWebdriver.WebDriver object
> ```
>
> ```python Python
> window_info = client.windows.get_window_info_for_playwright_page(session.data, page) # page is a playwright.Page object
> window_info = client.windows.get_window_info_for_selenium_driver(session.data, browser) # browser is a webdriver.Remote object
> ```

### Step 2

You may load the live view URL in your browser, or more likely, embed it in your application as an iframe.

```html
<iframe
  allow="clipboard-read;clipboard-write"
  title="<YOUR_BROWSER_ID>" // iframe elements require a unique title property
  id="<YOUR_BROWSER_ID>" // used to identify the iframe in live view message events
  src="<YOUR_LIVE_VIEW_URL>"
/>
```

Here's an example of what an embedded live view might look like in an application:

![Live View Embed](/_fern-files/_img/ce4456fc0d0ae0dadda884d4c0112f6621a06b8ef7a7142b2b40e7b62b6cbd49.webp)

### Step 3

You can optionally set up the live view to include a navigation bar, which will provide a URL bar and other controls to the user.

**`NodeJS`**

```typescript NodeJS
const windowInfo = await client.windows.getWindowInfo(session.data.id, windowId, {
  includeNavigationBar: true,
});
const liveViewUrl = windowInfo.data.liveViewUrl;
```

**`Python`**

```python Python
window_info = client.windows.get_window_info(session.data.id, window_id, include_navigation_bar=True)
live_view_url = window_info.data.live_view_url
```

![Live View with Navigation Bar](/_fern-files/_img/466cf993dff247007442d12ff5875bb21889c8f1b58607250b2090e030bedcd5.webp)

### Step 4

If you would like to receive messages from the Live View, you can set up a message listener in your application to let you know when certain events occur, such as when the page url changes. Check out the section below on [Messages](#messages) for more information.

## Controlling the Live View's dimensions

By default, the live view will resize to fit the wrapping iframe or window. You can control the Live View's size by simply adjusting the iframe's dimensions and the browser contents will resize to fit. However, you may also choose to set the screen resolution and disable resizing as shown below.

**`NodeJS`**

```typescript NodeJS
const windowInfo = await client.windows.getWindowInfo(session.data.id, windowId, {
  includeNavigationBar: true,
  screenResolution: "1920x1080", // Width x Height
  disableResize: true,
});
```

**`Python`**

```python Python
window_info = client.windows.get_window_info(session.data.id, window_id, include_navigation_bar=True, screen_resolution="1920x1080", disable_resize=True)
```

## Messages

The Live View iframe and parent window can communicate with each other via the [`window.postMessage` API](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage).
Each message has an `eventName` field that indicates the type of event, and some messages have a `payload` field containing relevant data.

To send and receive live view messages, you will first need to install the Airtop SDK for your frontend JS/TS app.

```bash
npm install @airtop/sdk
```

### Message handling in the parent window

You can set up a message listener in your application to handle messages from the Live View as shown below.

```typescript
import { LiveViewEventName, LiveViewMessage } from "@airtop/sdk";

window.addEventListener('message', function (event) {
  const iframe = document.getElementById('airtopLiveView');
  if (!iframe || event.source !== iframe.contentWindow) {
    // Message did not originate from the live view iframe
    return;
  }

  const message: LiveViewMessage = event.data;

  switch (message.eventName) {
    case LiveViewEventName.UrlChange: {
      handleUrlChange(message.payload); // Message payload is the new url
      break;
    }
    default: {
      return;
    }
  }
});
```

Whenever a relevant event occurs in the live view, the live view iframe will send a message to the parent window, which you can handle as appropriate for your use case.

### Sending messages to the live view

If you need your frontend application to send messages to the live view, you can use the `postMessage` API as shown below. Typically, if you use the built in navigation bar, you won't need to send messages to the live view, but if you have a custom navigation bar, you may need to use this mechanism to control the live view. Of course, your backend service can always control the browser and any changes will be reflected in the live view for your end users.

```typescript
import { LiveViewEventName, LiveViewMessage } from "@airtop/sdk";

const sendMessageToBrowser = (eventName: string, payload?: any) => {
  const message: LiveViewMessage = {
    eventName,
    ...(payload && { payload }),
  };

  const iframe = document.getElementById(browserId) as HTMLIFrameElement;

  if (!iframe) {
    return;
  }

  iframe.contentWindow.postMessage(message, 'https://live.airtop.ai');
};
```