Canvas
Use canvas to show HTML on connected Mac/iOS/Android nodes.
Model
- Canvas host serves files from
plugins.entries.canvas.config.host.root. - Canvas routes live on the Gateway HTTP port (
gateway.port, default18789). - Node bridge sends canvas URLs to connected node apps.
- Node apps render URLs in a WebView.
- Host name follows
gateway.bind: loopback local only, LAN IP for LAN, Tailscale host for tailnet, auto picks best route. - Localhost URLs only work for a node on the same machine.
- Paired nodes normally receive node-scoped
pluginSurfaceUrls.canvascapability URLs; prefer those when available.
Config
Active config: $OPENCLAW_CONFIG_PATH or ~/.openclaw/openclaw.json.
{
"plugins": {
"entries": {
"canvas": {
"config": {
"host": {
"enabled": true,
"root": "~/.openclaw/canvas",
"liveReload": true
}
}
}
}
},
"gateway": { "bind": "auto" }
}
Actions
present: show canvas, optional URL.hide: hide canvas.navigate: open new URL.eval: run JavaScript in current canvas.snapshot: capture screenshot.
Workflow
- Ensure Canvas plugin host is enabled.
- Put HTML/CSS/JS under
plugins.entries.canvas.config.host.rootor the default state canvas dir. - Use a route reachable by the target node.
- Present the hosted URL:
/__openclaw__/canvas/<file>.html. - Use
snapshotwhen the user needs proof.
URL shape
http://<gateway-host>:<gateway.port>/__openclaw__/canvas/index.html
http://<gateway-host>:<gateway.port>/__openclaw__/canvas/games/snake.html
Path mapping:
/__openclaw__/canvas/index.html-><canvas host root>/index.html/__openclaw__/canvas/games/snake.html-><canvas host root>/games/snake.html
Troubleshooting
- Node sees localhost but is remote: fix
gateway.bindor public URL, regenerate URL. - LAN node cannot load: verify same network, firewall, Gateway port, and auth/capability URL.
- Tailnet node cannot load: verify Tailscale status and advertised host.
- Blank page: open URL locally, check browser console, then snapshot node.
- Live reload missing: verify
liveReloadand file write under root.