Browser Automation: Let OpenClaw Take Over Real Web Workflows
Browser Automation: Let OpenClaw Take Over Real Web Workflows
How much of your day is spent on repetitive browser tasks? Logging into admin panels, scraping data from dashboards, filling out the same forms over and over. These workflows are predictable, step-by-step, and mind-numbing -- yet someone has to do them. That someone no longer needs to be you. OpenClaw's Browser Relay module lets your AI Agent operate a real browser just like a human would, turning hours of manual clicking into a single command.
This guide walks through the architecture, practical scenarios, and production-ready configuration for browser automation with OpenClaw.
What Is Browser Relay?
Browser Relay is OpenClaw's built-in browser control module. It acts as the bridge between your AI Agent and a real browser instance. Its core responsibilities include:
- Instruction translation: Converts the Agent's high-level intent into concrete browser actions
- Session management: Handles the full lifecycle of browser instances -- launching, reusing, and recycling them
- State synchronization: Feeds real-time page state (DOM snapshots, screenshots, network activity) back to the Agent
- Security isolation: Executes all operations within a sandboxed environment to prevent unauthorized access
Under the hood, Browser Relay is powered by Playwright and supports Chromium, Firefox, and WebKit. Think of it as a remote control for your browser -- the Agent issues commands, and Relay executes them and reports back.
# config/browser.yml
browser:
enabled: true
engine: "playwright"
browsers:
chromium:
enabled: true
headless: true
defaults:
viewport:
width: 1920
height: 1080
timeout: 30000
locale: "en-US"
Playwright Action Chains
Action chains are the execution units of Browser Relay. Each chain is an ordered sequence of steps, where each step maps to a browser operation: navigate, wait, click, type, extract, and so on.
OpenClaw defines action chains in YAML with support for variable interpolation and conditional logic:
steps:
- action: "navigate"
url: "https://example.com/page"
- action: "wait"
selector: "#target-element"
timeout: 5000
- action: "fill"
selector: "input[name='query']"
value: "{{search_term}}"
- action: "click"
selector: "button[type='submit']"
- action: "extract"
selector: ".result-list .item"
output_var: "results"
The power of action chains lies in composability. You can stitch small chains into complex workflows, or let the Agent generate them dynamically during a conversation.
Scenario 1: Automated Login to an Admin System
The most common use case: logging into a management dashboard every morning to check metrics or perform routine operations. Manually, this means opening a browser, entering credentials, waiting for redirects, and sometimes dealing with CAPTCHAs. With OpenClaw, it's a single command.
# config/forms.yml
forms:
admin_login:
url: "https://admin.example.com/login"
description: "Automated admin panel login"
steps:
- action: "navigate"
url: "https://admin.example.com/login"
- action: "wait"
selector: "#username"
timeout: 8000
- action: "fill"
selector: "#username"
value: "${ADMIN_USERNAME}"
- action: "fill"
selector: "#password"
value: "${ADMIN_PASSWORD}"
- action: "click"
selector: "button[type='submit']"
- action: "wait"
selector: ".dashboard-container"
timeout: 15000
message: "Waiting for dashboard to load"
- action: "screenshot"
path: "screenshots/login_success.png"
Running it:
# Execute the predefined login flow
claw forms run admin_login
# Schedule it to run every morning
claw schedule add --name "daily_login" \
--cron "0 9 * * *" \
--command "claw forms run admin_login"
Note that credentials are injected via environment variables (${ADMIN_USERNAME}). Never hardcode secrets in configuration files.
Scenario 2: Scraping Web Data and Organizing Results
Suppose you need to track competitor pricing daily, or export reports from an internal system that lacks an API. Browser Relay simulates real user behavior, making it effective even on pages that block simple HTTP scrapers.
scraping:
rules:
competitor_prices:
url: "https://competitor.example.com/products"
allowed: true
steps:
- action: "navigate"
url: "https://competitor.example.com/products"
- action: "wait"
selector: ".product-grid"
- action: "extract"
selector: ".product-card"
fields:
name: ".product-name"
price: ".product-price"
stock: ".stock-status"
output_var: "products"
pagination:
enabled: true
max_pages: 10
next_button: "a.next-page"
limits:
delay_between_requests: 3000
max_concurrent: 2
respect_robots_txt: true
Once the data is collected, the Agent can process it on the fly:
User: Scrape the competitor product pages and build a price comparison table.
Agent: On it. Navigating to the competitor site...
[browser_navigate to product listing]
[browser_extract product data]
[paginate and continue extraction]
Done. Collected 86 product entries. Here's the comparison:
| Category | Competitor Avg | Our Price | Delta |
|-------------|---------------|-----------|---------|
| Starter | $39 | $35 | -10.3% |
| Pro | $119 | $129 | +8.4% |
| Enterprise | $399 | $349 | -12.5% |
Recommendation: Our Pro tier is priced above the competitor average.
Consider a pricing review.
Scenario 3: Automated Form Submission
Bulk form submission comes up more often than you might expect: registering test accounts, filing support tickets, submitting expense reports, or populating a CMS.
forms:
expense_report:
url: "https://oa.example.com/expense/new"
description: "Automated expense report submission"
steps:
- action: "navigate"
url: "https://oa.example.com/expense/new"
- action: "wait"
selector: "form.expense-form"
- action: "fill"
selector: "input[name='title']"
value: "{{expense.title}}"
- action: "fill"
selector: "input[name='amount']"
value: "{{expense.amount}}"
- action: "select"
selector: "select[name='category']"
value: "{{expense.category}}"
- action: "fill"
selector: "textarea[name='description']"
value: "{{expense.description}}"
- action: "upload"
selector: "input[type='file']"
file: "{{expense.receipt_path}}"
- action: "click"
selector: "button.submit-btn"
- action: "wait"
selector: ".success-toast"
timeout: 10000
- action: "extract"
selector: ".expense-id"
output_var: "expense_number"
Run it in bulk:
# Submit multiple reports from a CSV file
claw forms run expense_report \
--data-file expenses.csv \
--delay 2000
Configuration Essentials
Headless vs Headed Mode
browser:
browsers:
chromium:
headless: true # Headless: for servers and CI/CD pipelines
# headless: false # Headed: for debugging, shows the browser window
- Headless: Recommended for production. Lower resource usage, works in Docker without a display server.
- Headed: Use during development. You can watch every click and input in real time, making it much easier to debug selectors and timing issues.
Timeout Handling
browser:
defaults:
timeout: 30000 # Global default: 30 seconds
retry:
enabled: true
max_attempts: 3
backoff: "exponential" # 1s, 2s, 4s
retry_on:
- "TimeoutError"
- "NavigationError"
Error Recovery Strategy
Flaky networks and slow page loads are a fact of life. A robust retry strategy is essential for production use:
automation:
error_handling:
retry:
max_attempts: 3
initial_delay: 1000
max_delay: 10000
backoff_multiplier: 2
fallback:
on_timeout: "screenshot_and_skip"
on_element_not_found: "retry_with_alternative_selector"
on_navigation_error: "clear_cache_and_retry"
on_failure:
notify:
- channel: "telegram"
user_id: "${ADMIN_TELEGRAM_ID}"
Security Considerations
Browser automation involves real network interactions. Security cannot be an afterthought:
- Credential management: All usernames and passwords must be injected via environment variables or a secrets manager. Never hardcode them.
- Domain allowlisting: Strictly limit which domains the Agent can access. This prevents prompt injection attacks from redirecting the browser to malicious URLs.
- Sandbox isolation: Run browser instances inside Docker containers, isolated from the host system.
- Operation auditing: Log every browser action for post-incident review and compliance.
- Rate limiting: Set reasonable delays between requests to avoid triggering anti-bot mechanisms on target sites.
- Respect robots.txt: Always honor the crawling policies of target websites.
browser:
security:
sandbox: true
allowed_domains:
- "*.your-company.com"
- "admin.example.com"
block_downloads: true
cookies:
clear_on_exit: true
accept_third_party: false
Wrapping Up
Browser Relay transforms OpenClaw from a conversational assistant into an agent that can take real action in the browser. With Playwright action chains, any repetitive web workflow can be encoded as an automation pipeline. Here's the practical playbook:
- Start small -- get a single login or scrape flow working end to end
- Layer in error handling and retry logic incrementally
- Always put security first -- allowlists, sandboxing, credential management
- Debug in headed mode, deploy in headless mode
Hand the mechanical work to your Agent. Keep the creative work for yourself.
Related Posts
Related Tutorial Chapters

Follow WeChat: 彭少
Stay updated with OpenClaw tips, AI coding techniques, and productivity tools. Follow for the latest content.

