Skip to content

Commit 025e414

Browse files
committed
Add Live View and Human in the Loop feature docs
1 parent 5cb68c3 commit 025e414

2 files changed

Lines changed: 237 additions & 0 deletions

File tree

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
---
2+
pcx_content_type: how-to
3+
title: Human in the Loop
4+
description: Temporarily hand off browser control to a human operator for authentication, sensitive actions, or tasks that are difficult to fully automate.
5+
sidebar:
6+
order: 3
7+
badge: Beta
8+
---
9+
10+
Some browser automation workflows require manual intervention. A login page may need multi-factor authentication, a form may require sensitive credentials you do not want to pass to an automation script, or a task may be too complex to fully automate. Human in the Loop lets you pause an automation script and hand off control to a human operator through [Live View](/browser-rendering/features/live-view/), then resume the script once the human is done.
11+
12+
## How it works
13+
14+
Human in the Loop builds on [Live View](/browser-rendering/features/live-view/) and the [CDP](/browser-rendering/cdp/) endpoints:
15+
16+
1. Your automation script navigates to a page that needs human input
17+
2. The script retrieves the Live View URL via `Cloudflare.getLiveView` and shares it with a human operator (for example, by logging it, sending it via Slack, or displaying it in a UI)
18+
3. The human operator opens the Live View URL and completes the required action (logging in, solving a CAPTCHA, entering sensitive data, etc.)
19+
4. The automation script detects that the human is done (for example, by waiting for a navigation event or polling for a page element) and resumes
20+
21+
## Example: login with human assistance
22+
23+
This example uses [Puppeteer](/browser-rendering/puppeteer/) connected to Browser Run via the [CDP](/browser-rendering/cdp/) endpoints. The script navigates to a login page, shares a Live View URL for a human to enter credentials, then continues the automation after login completes.
24+
25+
```js
26+
import puppeteer from "puppeteer-core";
27+
28+
const ACCOUNT_ID = "your-account-id";
29+
const API_TOKEN = "your-api-token";
30+
31+
// Create a browser session via CDP
32+
const response = await fetch(
33+
`https://api.cloudflare.com/client/v4/accounts/${ACCOUNT_ID}/browser-rendering/devtools/browser?keep_alive=600000`,
34+
{
35+
method: "POST",
36+
headers: { Authorization: `Bearer ${API_TOKEN}` },
37+
}
38+
);
39+
const { webSocketDebuggerUrl } = await response.json();
40+
41+
// Connect Puppeteer to the session
42+
const browser = await puppeteer.connect({
43+
browserWSEndpoint: webSocketDebuggerUrl,
44+
headers: { Authorization: `Bearer ${API_TOKEN}` },
45+
});
46+
47+
const page = await browser.newPage();
48+
await page.goto("https://example.com/login");
49+
50+
// Get the Live View URL so a human can interact with the session
51+
const cdp = await page.createCDPSession();
52+
const { devtoolsFrontendUrl: liveUrl } = await cdp.send(
53+
"Cloudflare.getLiveView"
54+
);
55+
56+
// Share the Live View URL with the human operator
57+
console.log(`Human input needed. Open this URL: ${liveUrl}`);
58+
59+
// Wait for the human to complete login
60+
await page.waitForNavigation({ waitUntil: "networkidle0", timeout: 300000 });
61+
62+
// Login complete, continue automation
63+
const cookies = await page.cookies();
64+
console.log("Login complete. Continuing automation...");
65+
66+
await page.goto("https://example.com/dashboard");
67+
const content = await page.content();
68+
69+
browser.disconnect();
70+
```
71+
72+
## Use cases
73+
74+
- **Authentication flows**: Login pages with MFA, SSO, or CAPTCHA that cannot be bypassed programmatically
75+
- **Sensitive data entry**: Forms requiring credentials or personal information you do not want to pass to an automation script
76+
- **Complex interactions**: One-off tasks that are too difficult or not worth fully automating, such as configuring a dashboard or approving a workflow
77+
- **Verification steps**: Confirming an order, reviewing generated content, or approving an action before the script proceeds
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
---
2+
pcx_content_type: how-to
3+
title: Live View
4+
description: View and interact with remote Browser Run sessions in real time using the hosted DevTools UI or native Chrome DevTools.
5+
sidebar:
6+
order: 2
7+
badge: Beta
8+
---
9+
10+
import { CURL, DashButton, Tabs, TabItem } from "~/components";
11+
12+
Live View lets you see and interact with a remote Browser Run session in real time. This is useful for debugging automation scripts, monitoring what a browser is doing, or manually stepping in when a task requires human intervention (see [Human in the Loop](/browser-rendering/features/human-in-the-loop/)).
13+
14+
Live View is available for any browser session created through the [CDP](/browser-rendering/cdp/) endpoints.
15+
16+
## How to access Live View
17+
18+
There are three ways to access Live View: through the Cloudflare dashboard, via the hosted UI at `live.browser.run`, or using native Chrome DevTools.
19+
20+
### Cloudflare dashboard
21+
22+
In the Cloudflare dashboard, go to the **Browser Run** page and select the **Live Sessions** tab. This shows all active browser sessions in your account. Expand a session to see its tabs, then select **Open** to open the Live View for that tab.
23+
24+
<DashButton url="/?to=/:account/workers/browser-rendering" />
25+
26+
### Hosted UI (any browser)
27+
28+
When you create a session or list targets through the [CDP](/browser-rendering/cdp/) endpoints, the API response includes a `devtoolsFrontendUrl` for each target (tab). Open this URL in any browser to load the DevTools UI hosted at `live.browser.run`, which streams the remote session to your browser.
29+
30+
The hosted UI supports three viewing modes, controlled by the `mode` parameter in the URL:
31+
32+
| Mode | URL pattern | Description |
33+
| --- | --- | --- |
34+
| Tab | `https://live.browser.run/ui/view?mode=tab&wss=...` | DevTools inspector panel (Elements, Console, Network, etc.) |
35+
| Full | `https://live.browser.run/ui/view?mode=full&wss=...` | Full browser chrome with address bar and tab strip |
36+
| Inspector | `https://live.browser.run/ui/inspector?wss=...` | Standalone inspector view |
37+
38+
### Native Chrome DevTools (Chrome only)
39+
40+
Because Browser Run speaks standard CDP, you can connect Chrome's built-in DevTools directly to a remote session. Replace the `https://live.browser.run/ui/inspector?wss=` prefix in the `devtoolsFrontendUrl` with the `devtools://` protocol:
41+
42+
```
43+
devtools://devtools/bundled/inspector.html?wss=live.browser.run/api/devtools/browser/SESSION_ID/page/TARGET_ID?jwt=...
44+
```
45+
46+
Paste this URL into Chrome's address bar to open native DevTools connected to the remote browser session.
47+
48+
**Pros:**
49+
- Familiar UI: the exact same DevTools you use daily for local development, rather than a hosted version wrapped inside a webpage
50+
- Slightly faster to load: DevTools assets (HTML, JS, CSS) are already bundled locally in Chrome
51+
52+
**Cons:**
53+
- Chrome only: the `devtools://` protocol URL only works in Chrome. The hosted `live.browser.run` version works in other browsers, though the DevTools UI has not been heavily tested outside Chrome.
54+
- Inspector tab only: does not work for the full or tab viewing modes
55+
56+
:::caution[URL validity]
57+
The `devtoolsFrontendUrl` is valid for five minutes from when it was generated. If you do not open the URL within this timeframe, list the targets again to get a fresh URL. Once the DevTools connection is established, it remains active as long as the browser session is alive.
58+
:::
59+
60+
## View a new session
61+
62+
1. Create a browser session with `targets=true` to include target URLs in the response:
63+
64+
<CURL
65+
url="https://api.cloudflare.com/client/v4/accounts/ACCOUNT_ID/browser-rendering/devtools/browser"
66+
method="POST"
67+
headers={{
68+
Authorization: "Bearer {api_token}",
69+
}}
70+
query={{
71+
keep_alive: "600000",
72+
targets: "true",
73+
}}
74+
/>
75+
76+
```json
77+
{
78+
"sessionId": "1909cef7-23e8-4394-bc31-27404bf4348f",
79+
"targets": [
80+
{
81+
"description": "",
82+
"devtoolsFrontendUrl": "https://live.browser.run/ui/inspector?wss=live.browser.run/api/devtools/browser/1909cef7-.../page/8E598E99...?jwt=...",
83+
"id": "8E598E996530FB09E46A22B8B7754F7F",
84+
"title": "about:blank",
85+
"type": "page",
86+
"url": "about:blank",
87+
"webSocketDebuggerUrl": "wss://live.browser.run/api/devtools/browser/1909cef7-.../page/8E598E99...?jwt=..."
88+
}
89+
],
90+
"webSocketDebuggerUrl": "wss://api.cloudflare.com/client/v4/accounts/{account_id}/browser-rendering/devtools/browser/1909cef7-..."
91+
}
92+
```
93+
94+
2. Copy the `devtoolsFrontendUrl` from `targets[0]` and open it in your browser. You now have a live, interactive view of the remote browser session.
95+
96+
## View an existing session
97+
98+
If you have a running session and want to connect to it:
99+
100+
1. List your active sessions:
101+
102+
<CURL
103+
url="https://api.cloudflare.com/client/v4/accounts/ACCOUNT_ID/browser-rendering/devtools/session"
104+
method="GET"
105+
headers={{
106+
Authorization: "Bearer {api_token}",
107+
}}
108+
/>
109+
110+
2. Using the session ID, list the targets in that session:
111+
112+
<CURL
113+
url="https://api.cloudflare.com/client/v4/accounts/ACCOUNT_ID/browser-rendering/devtools/browser/SESSION_ID/json/list"
114+
method="GET"
115+
headers={{
116+
Authorization: "Bearer {api_token}",
117+
}}
118+
/>
119+
120+
```json
121+
[
122+
{
123+
"id": "110850A800BDB8B593CDDA30676635CF",
124+
"type": "page",
125+
"url": "https://example.com",
126+
"title": "Example Domain",
127+
"description": "",
128+
"devtoolsFrontendUrl": "https://live.browser.run/ui/view?wss=live.browser.run/api/devtools/browser/28d75446-.../page/110850A8...?jwt=...",
129+
"webSocketDebuggerUrl": "wss://live.browser.run/api/devtools/browser/28d75446-.../page/110850A8...?jwt=..."
130+
}
131+
]
132+
```
133+
134+
3. Copy the `devtoolsFrontendUrl` and open it in your browser.
135+
136+
## Get the Live View URL programmatically
137+
138+
You can retrieve the Live View URL from within a Puppeteer or Playwright script using a CDP command. This is useful when you need to share the URL with someone, for example sending it via email, Slack, or displaying it in a UI.
139+
140+
<Tabs> <TabItem label="Puppeteer">
141+
142+
```js
143+
const cdp = await page.createCDPSession();
144+
const { devtoolsFrontendUrl } = await cdp.send("Cloudflare.getLiveView");
145+
146+
console.log(`Live View: ${devtoolsFrontendUrl}`);
147+
```
148+
149+
</TabItem> <TabItem label="Playwright">
150+
151+
```js
152+
const cdp = await page.context().newCDPSession(page);
153+
const { devtoolsFrontendUrl } = await cdp.send("Cloudflare.getLiveView");
154+
155+
console.log(`Live View: ${devtoolsFrontendUrl}`);
156+
```
157+
158+
</TabItem> </Tabs>
159+
160+
You can also get the Live View URL from the HTTP API by listing targets for a session, as shown in [View an existing session](#view-an-existing-session). Each target in the response includes a `devtoolsFrontendUrl`.

0 commit comments

Comments
 (0)