Skip to content

Session live view

An interactive window to display or control a browser session.

Updated View as Markdown

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


Uses

While Browsers helps with bot protection systems, data extraction, and reliable file 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 to enable uploads through the live view
  • Embedding - use within an application (both desktop and mobile)

Getting started

Also check out the Live Views API endpoint.

const liveViewLinks = await browsers.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);
live_view_links = browsers.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)

Multitab

Each tab has a unique live view url.

The pages property contains all live view urls.

Listen for the Playwright new tab event (or equivalent in other libraries) to fetch new live view urls as tabs open.

// 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 browsers.sessions.debug(session.id);
const allTabs = liveViewLinks.pages;
const secondTabLiveViewLink = allTabs[1].debuggerFullscreenUrl;
console.log(`Second Tab Live View Link: ${secondTabLiveViewLink}`);
# 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 = browsers.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}")

Embedding

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

<iframe
  src="{liveViewLink}"
  sandbox="allow-same-origin allow-scripts"
  allow="clipboard-read; clipboard-write"
  style="pointer-events: none;"
/>
<iframe
  src="{liveViewLink}"
  sandbox="allow-same-origin allow-scripts"
  allow="clipboard-read; clipboard-write"
/>

Mobile

Show a mobile live view by setting a session’s viewport.

// Standard android mobile dimensions
browserSettings: {
  viewport: {
    width: 360,
    height: 800,
  },
},
// ...other session configuration options
# Standard android mobile dimensions
browser_settings={
  "viewport": {
    "width": 360,
    "height": 800
  }
},
# ...other session configuration options

To display a keyboard with a mobile live view, use a library like react-simple-keyboard.

Handling disconnects

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

You can listen for this event programmatically:

window.addEventListener("message", function (event) {
  if (event.data === "agentmq-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.

const liveViewLinks = await browsers.sessions.debug(session.id);
const liveViewLink = liveViewLinks.debuggerUrl;
console.log(`Live View Link - with borders: ${liveViewLink}`);
live_view_links = browsers.sessions.debug(session.id)
live_view_link = live_view_links.debuggerUrl
print(f"Live View Link - with borders: {live_view_link}")

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.

const hiddenNavbarUrl = `${liveViewLink}&navbar=false`;
hidden_navbar_url = f"{live_view_link}&navbar=false"

Hide the scrollbar

// 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);
});
// 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);
`);
# Navigate to the page
page.goto("https://agent.mq")

# Hide the scrollbar
page.evaluate("""
  const style = document.createElement('style');
  style.textContent = '::-webkit-scrollbar { display: none; }';
  document.head.appendChild(style);
""")
# Navigate to the page
driver.get("https://example.com")

# Hide the scrollbar
driver.execute_script("""
  style = document.createElement("style");
  style.textContent = "::-webkit-scrollbar { display: none; }";
  document.head.appendChild(style);
""")

Troubleshooting

  1. Blank or empty window

    You may be on another tab. Check if there are multiple tabs open via the web session inspector or the pages list.

  2. Lag

    Check out the performance guide.

  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 agentmq-disconnected message. See Handling Disconnects for how to listen for this event.

Navigation

Type to search…

↑↓ navigate↵ selectEsc close