Why Headful?
Debugging
Step through tasks visually to identify why a selector fails.
Manual Intervention
Solve CAPTCHAs or complete complex 2FA flows that automation cannot handle.
Exploration
Browse sites naturally to discover selectors and API endpoints.
Recording
Create high-fidelity video demonstrations of your automation.
Starting a Headful Session
1
Open a task in the editor
Navigate to the Task Editor and open the task you want to debug.
2
Launch the browser
Click Open Browser in the editor panel to log in or debug visually.
Controls
The VNC interface provides a standard desktop environment:- Mouse/Keyboard: Full interaction support.
- Clipboard: Copy/paste text between your host and the remote browser.
- Resolution: The viewport resizes dynamically (default 1920x1080).
Popups and multi-page navigation
Headful sessions automatically track the active browser page across popups and new tabs. When a site opens a popup — for example, an OAuth login window or a payment gateway — Figranium switches to the new page so you can interact with it in the VNC viewer. When that page closes, the session returns to the previous page. This means workflows that span multiple pages work without any extra configuration:- OAuth and SSO flows: Complete third-party login prompts that open in a popup.
- Payment windows: Interact with payment providers that redirect through a new tab.
- Multi-tab browsing: Open links in new tabs and switch between them naturally.
Persistence
Headful sessions use a dedicated persistent browser profile directory (data/browser-profile-headful). Cookies are automatically synced to agent and scrape runs via data/headful-storage-state.json:
- Sync interval: Every 30 seconds while a headful session is active.
- Sync on close: Cookies are also saved when the headful session is stopped via Close Browser.
- Agent & scrape pickup: Each non-stateless agent or scrape run injects the saved cookies at startup, so they pick up any session established in headful.
1
Login once
Log in manually in the headful browser.
2
Automate
Run an Agent or Scrape task — it will automatically have those cookies available.
Only non-expired cookies are synced. If
headful-storage-state.json does not exist yet (no headful session has run), agent and scrape runs simply start with their own profile cookies.statelessExecution to launch a clean, incognito-like session that won’t save cookies and won’t receive headful cookies.
Element picking
The headful browser doubles as a selector discovery tool. When you click the Highlight Tool icon in an action block’s selector field, Figranium opens a headful session with inspect mode already active — no extra step required.- The crosshair overlay appears automatically in the VNC viewer.
- Hover over any element to see it highlighted with a tooltip showing the top selector candidates.
- Click the element to confirm your selection.
Variable support
Headful sessions resolve task variables in the starting URL. For example, if your task defines a variablesite, you can set the headful URL to:
API integration
You can start a headful session programmatically:Stopping
Click Close Browser in the Editor to terminate the session and close the browser. This ensures resources are freed.Crash resilience and auto-reconnect
The three processes that back the headful viewer — Xvfb, x11vnc, and websockify — each run inside a restart loop. If any one of them exits, the container restarts it within a second and appends the event to its per-process log:data/xvfb.logdata/x11vnc.logdata/novnc.log
- Reconnecting… — the previous session was open for at least 4 seconds before dropping, so the disconnect is treated as a network blip.
- Browser session crashed, retrying… — the session dropped within 4 seconds of connecting, which usually means Xvfb or x11vnc crashed and the viewer is waiting for the restart loop to bring it back.
linux/arm64 image. Running the AMD64 image under QEMU emulation is the most common cause of the fast-crash pattern above. See Troubleshooting — Headful viewer shows “Connecting…” then “Disconnected” on Apple Silicon Macs.
Access control
Figranium’s VNC stack is hardened against unauthenticated access. If you connect to it through the embedded viewer in the UI, everything works automatically — this section is only relevant if you build a custom client or open a raw VNC connection.Network binding
x11vnc (port 5900) binds to 127.0.0.1 inside the container and is not reachable from outside. websockify (port 54311) binds to 0.0.0.0 so it can be reached over a Docker port forward. This is what makes the headful viewer work on Apple Silicon Macs and other setups that rely on port forwarding into the container.
Exposing 54311 to the network is not the same as leaving VNC unauthenticated. Every WebSocket upgrade to 54311 is checked against the same rules as /websockify on the main Figranium port: ALLOWED_IPS, Origin/Host match, and a valid session cookie or API key. Direct RFB connections to port 5900 are still impossible from outside the container.
For production, keep publishing the main Figranium port (default
11345) and route the viewer through wss://<host>:11345/websockify. Only publish 54311 if you need direct access from a custom noVNC client, and put it behind the same auth as any other Figranium endpoint.VNC password
On first start, Figranium generates a random VNC password and writes it todata/vnc_password.txt. x11vnc requires this password for every connection, so a client that reaches port 5900 still cannot attach without it.
The embedded noVNC viewer fetches the password automatically from an authenticated endpoint before connecting — you do not need to type it in.
To retrieve the password for a custom client:
GET /api/headful/vnc-password.
Authenticated WebSocket upgrades
Every WebSocket upgrade to/websockify (used by noVNC) is validated before the connection is proxied to the VNC server. Requests must satisfy all of the following:
- Originate from an IP address permitted by
ALLOWED_IPS. - Present an
Originheader that matches the requestHost(CSWSH protection). If bothOriginandHostresolve to loopback or private addresses (localhost,127.0.0.1,::1,host.docker.internal, any*.localhostname, or an RFC 1918 private range), the ports and aliases do not need to match. This lets Vite dev servers, Docker port mappings, and IPv6 loopback aliases connect without tripping the CSWSH check while still rejecting cross-origin upgrades from public hosts. - Carry either a valid session cookie or an API key (
x-api-keyheader or?apiKey=query parameter).
[SECURITY] prefix on the server console.
If you build a custom noVNC client, pass your API key on the WebSocket URL: