Canvas
Display HTML content on connected OpenClaw nodes (Mac app, iOS, Android). Great for games, visualizations, and dashboards.
Canvas is OpenClaw's built-in system for displaying HTML content on connected nodes — Mac app, iOS, and Android. It turns any OpenClaw node into a display surface for games, dashboards, visualizations, and interactive demos. Think of it as AirPlay for AI-generated content.
The architecture is elegant: a lightweight HTTP server (port 18793) serves static HTML/CSS/JS files from a configurable root directory. The node bridge communicates canvas URLs to connected apps, which render them in a WebView. Live reload is built in — save a file and it updates instantly on all connected displays.
Canvas supports Tailscale integration for remote access. Depending on your gateway bind mode (loopback, LAN, tailnet, auto), canvas URLs are constructed with the appropriate hostname. This means you can push content to a phone across the internet via Tailscale, not just on your local network.
The workflow is simple: create an HTML file in your canvas root directory, then use the canvas tool to present it on a specific node. You can navigate between pages, execute JavaScript in the canvas context, take screenshots for AI analysis, and hide the canvas when done.
For OpenClaw users, this opens up creative possibilities: build a Snake game and push it to your phone, create a real-time dashboard showing system metrics, display weather visualizations, or build interactive demos. The AI generates the HTML, the canvas displays it — no app deployment needed.
Best suited for: OpenClaw users with connected nodes (Mac/iOS/Android apps), developers prototyping interactive visualizations, anyone wanting to push AI-generated UI to physical devices.
Tags: canvas, html, visualization, dashboard, ui
Category: UI
Use Cases
- Push AI-generated games to your phone (Snake, Tetris, quizzes)
- Display real-time dashboards on a Mac or iPad
- Show weather visualizations or data charts
- Interactive demos and prototypes without app deployment
- Remote display control via Tailscale for presentations
- Periodic dashboard updates via cron + canvas navigate
Tips
- Use live reload during development — set `liveReload: true` in canvasHost config
- Keep HTML self-contained with inline CSS and JS for best cross-platform results
- Use the snapshot action to capture what's displayed for AI analysis
- Test your canvas URL with curl before pushing to a node
- Find your Tailscale hostname: `tailscale status --json | jq -r '.Self.DNSName'`
- The default index.html has bridge diagnostics — use it to verify connectivity
- Use `canvas action:eval` to run JavaScript on the displayed page dynamically
Known Issues & Gotchas
- Node must be connected and online — use `openclaw nodes list` to verify
- URL must match your gateway bind mode — localhost URLs won't work for remote nodes
- Always specify the node parameter — 'node required' error means you forgot it
- Canvas persists until you explicitly `hide` it — it won't auto-dismiss
- Tailscale hostname is used when bound to tailnet — nodes receive the Tailscale URL, not localhost
- Keep HTML self-contained (inline CSS/JS) for most reliable rendering across platforms
- A2UI JSON push is still WIP — use HTML files for now
Alternatives
- Screen Mirroring (AirPlay/Miracast)
- Home Assistant Dashboard
- MagicMirror²
- Browser tab (manual)
Community Feedback
The canvas tool lets you present web content on any connected node's canvas view. Great for displaying games, visualizations, and dashboards.
— OpenClaw Docs
Canvas with live reload makes development incredibly fast — just save the HTML file and it updates on all connected devices instantly.
— OpenClaw Community
Configuration Examples
Enable canvas host in openclaw.json
{
"canvasHost": {
"enabled": true,
"port": 18793,
"root": "/Users/you/clawd/canvas",
"liveReload": true
},
"gateway": {
"bind": "auto"
}
}Present HTML on a node
canvas action:present node:<node-id> target:http://<hostname>:18793/__openclaw__/canvas/my-game.htmlEvaluate JavaScript in the canvas
canvas action:eval node:<node-id> javaScript:"document.title = 'Updated!'"Installation
# Built-in (bundled with OpenClaw)Source: bundled