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 optionsTo 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
-
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.
-
Lag
Check out the performance guide.
-
Looks off
Often caused by headless browser rendering differences. Some issues may be fixable by adjusting CSS styling through
page.evaluate(). -
Lost Connection
If the live view loses its connection to the browser, the iframe will post a
agentmq-disconnectedmessage. See Handling Disconnects for how to listen for this event.