- The browser relay is a WebSocket proxy built into the OpenClaw gateway that lets web browsers connect directly to your agent network
- Enable it with three lines in gateway.yaml — no separate process, no extra dependency
- Always set a strict allowed_origins list in production; a wildcard opens your agent network to any website
- The relay handles session management and message queuing automatically — reconnections don't lose messages
- Works with any JavaScript framework using the native WebSocket API or any WS-compatible library
Building a web chat interface on top of OpenClaw takes 90% less code when you use the browser relay. Without it, you need a custom backend to proxy messages, handle WebSocket connections, manage sessions, and bridge the auth gap between the browser and your gateway. With it, your frontend speaks directly to agents. Here's how to set that up correctly.
What the Browser Relay Actually Does
The browser relay is a WebSocket endpoint built into the OpenClaw gateway. It sits at /relay on your gateway URL and accepts connections from browser-based clients. When a browser sends a message through the relay, the gateway routes it to the appropriate agent channel — exactly as if it had arrived via Telegram or any other registered channel.
This matters because browsers can't authenticate with the gateway the same way a server-side agent client can. The relay bridges that gap by handling authentication at the gateway level. The browser sends a short-lived session token, the gateway validates it against its token store, and then proxies all subsequent messages to the correct agent.
The relay also handles reconnection. WebSocket connections drop. Mobile browsers kill background connections. The relay queues messages that arrive during a disconnection and delivers them when the client reconnects — provided the queue TTL hasn't expired. You configure that TTL. Most setups use 60–300 seconds depending on the expected session length.
As of early 2025, the browser relay is enabled by default in new OpenClaw installations but requires explicit configuration before it becomes functional. A gateway with no browser_relay block in gateway.yaml will refuse all relay connections with a 404.
Enabling the Browser Relay in gateway.yaml
The configuration lives in your gateway.yaml file under the browser_relay key. Here's the minimal production-ready configuration.
# gateway.yaml
gateway:
token: "your-gateway-token"
port: 8080
browser_relay:
enabled: true
allowed_origins:
- "https://yourdomain.com"
- "https://app.yourdomain.com"
session_ttl: 3600 # seconds before session expires
queue_ttl: 120 # seconds to queue messages during disconnect
max_connections: 500 # per-gateway connection limit
auth:
mode: "token" # options: token, jwt, none
token_header: "X-Relay-Token"
The allowed_origins list is your first security layer. The gateway checks the Origin header on every incoming WebSocket handshake against this list. Requests from unlisted origins are rejected with a 403 before any authentication happens.
Setting allowed_origins: ["*"] means any website — including malicious ones — can initiate relay connections from a visitor's browser. This exposes your agent network to cross-site request abuse. Always list exact origins, including the protocol and subdomain.
After saving the file, restart the gateway process. The relay endpoint becomes active immediately — no additional service to start, no port to open separately. The relay runs on the same port as the rest of the gateway, multiplexed over the same connection.
Connecting From a Web Frontend
The browser side uses standard WebSocket protocol. No special SDK required — the native WebSocket API in every modern browser works fine.
// Connect to the OpenClaw browser relay
const relay = new WebSocket('wss://your-gateway.example.com/relay');
// Send authentication immediately after connection opens
relay.addEventListener('open', () => {
relay.send(JSON.stringify({
type: 'auth',
token: 'your-session-token',
channel: 'support-agent-001'
}));
});
// Handle incoming agent messages
relay.addEventListener('message', (event) => {
const data = JSON.parse(event.data);
if (data.type === 'message') {
displayAgentResponse(data.content);
}
});
// Send a user message to the agent
function sendMessage(text) {
relay.send(JSON.stringify({
type: 'message',
content: text
}));
}
// Handle disconnection with automatic reconnect
relay.addEventListener('close', () => {
setTimeout(() => reconnect(), 2000);
});
The authentication message must be the first thing sent after the connection opens. The gateway enforces a short auth timeout — typically 5 seconds — and will close unauthenticated connections automatically. Send the auth payload in the open event handler, not in a setTimeout.
Sound familiar? This pattern is identical to how Slack, Discord, and Linear handle their real-time connections. The relay follows the same conventions those teams have proven at scale.
Generating Session Tokens
Your backend generates session tokens and passes them to the browser. The browser never holds your gateway token — it holds a short-lived session token that the gateway can validate and revoke independently. This separation is the correct architecture.
# Backend: Generate a relay session token (Python example)
import httpx
response = httpx.post(
'https://your-gateway.example.com/api/v1/relay/sessions',
headers={'Authorization': 'Bearer your-gateway-token'},
json={'channel': 'support-agent-001', 'ttl': 3600}
)
session_token = response.json()['token']
# Return session_token to the browser client
Security Configuration for Production
The allowed_origins check and session token architecture cover most attack surface. There are three additional settings worth configuring before you go live.
Rate limiting per session. Without rate limits, a single browser tab can flood the relay with messages and overwhelm your LLM API quota. Add a rate_limit block under browser_relay to cap messages per session per minute.
browser_relay:
enabled: true
allowed_origins:
- "https://yourdomain.com"
rate_limit:
messages_per_minute: 30
burst: 10
tls:
enforce: true # reject plaintext ws:// connections
TLS enforcement. Set tls.enforce: true to reject plaintext ws:// connections. Browsers on HTTPS pages will refuse ws:// connections anyway due to mixed content rules — but this setting also protects API clients hitting the relay from non-browser contexts.
Connection limits. The max_connections setting caps total concurrent relay connections across all sessions. Set it based on your gateway's available memory — each connection uses roughly 50–100KB depending on queue depth. A 2GB gateway can handle 8,000–10,000 concurrent relay connections before memory becomes a constraint.
If you're running both internal agent-to-agent communication and browser-facing relay connections through one gateway, consider splitting them. Browser traffic patterns — bursty, high connection count, variable session length — are different from internal agent traffic. A dedicated relay gateway lets you scale them independently.
Common Mistakes That Break the Browser Relay
- Sending auth after a delay — wrapping the auth message in a
setTimeoutinstead of sending it immediately in theopenhandler causes the gateway to close the connection before auth completes. Always send auth synchronously in the open handler. - Forgetting the protocol prefix — browser relay connections use
wss://(WebSocket Secure) for HTTPS gateways, nothttps://. Using the wrong protocol gives a cryptic connection error that looks like a CORS issue. - Mismatched channel IDs — the channel specified in the auth payload must exactly match a registered agent channel. Typos and case mismatches result in a silent 404 response from the relay, which looks like an auth failure in browser dev tools.
- Not handling the close event — browser relay connections drop. Mobile networks drop them constantly. An app without a reconnect handler leaves users staring at a broken chat UI with no error message.
- Hardcoding the gateway token in frontend code — the gateway token must never appear in browser JavaScript. Generate short-lived session tokens server-side and pass only those to the browser. The gateway token gives full control of your agent network.
Frequently Asked Questions
What is the OpenClaw browser relay?
The browser relay is a WebSocket proxy built into the OpenClaw gateway that lets browser-based clients connect directly to agent channels. It handles CORS, authentication bridging, session management, and message queuing — eliminating the need for a custom backend layer between your web frontend and your agents.
How do I enable the browser relay in gateway.yaml?
Add a browser_relay block with enabled: true and an allowed_origins list containing your frontend domain. Restart the gateway after saving. The relay endpoint becomes available immediately at /relay on your gateway URL.
Is the browser relay secure for production use?
Yes, when configured correctly. Set a strict allowed_origins list, enable token-based session authentication, enforce TLS, and configure rate limiting. Never use a wildcard origin — it allows any website to connect to your agent network from a visitor's browser.
Can I use the browser relay with any JavaScript framework?
Yes. The relay uses standard WebSocket protocol. React, Vue, Svelte, Angular, and vanilla JavaScript all work with the native WebSocket API. No special SDK is required. Any WebSocket-compatible library also works — the relay doesn't use proprietary extensions.
What happens if the browser relay drops a connection?
The relay queues messages sent during a disconnection and delivers them when the client reconnects, provided the queue_ttl hasn't expired. Configure queue_ttl in gateway.yaml to match your expected session length — 60 to 300 seconds covers most use cases.
Does the browser relay work with multiple agents simultaneously?
Yes. Each browser session can be routed to different agent channels by specifying the target channel in each message payload. One browser tab can orchestrate multiple agents. The relay multiplexes connections, so you don't need separate WebSocket connections per agent.
S. Rivera has deployed OpenClaw gateway configurations across cloud and on-premise environments, including browser relay setups serving tens of thousands of concurrent users. Focuses on the intersection of agent infrastructure and web application architecture.