---
name: canvas
description: "Present HTML on connected OpenClaw node canvases, navigate/eval/snapshot, and debug canvas host URLs."
metadata: { "openclaw": { "emoji": "🖼️" } }
---
# 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`, default `18789`).
- 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.canvas` capability URLs; prefer those when available.
## Config
Active config: `$OPENCLAW_CONFIG_PATH` or `~/.openclaw/openclaw.json`.
```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
1. Ensure Canvas plugin host is enabled.
2. Put HTML/CSS/JS under `plugins.entries.canvas.config.host.root` or the default state canvas dir.
3. Use a route reachable by the target node.
4. Present the hosted URL: `/__openclaw__/canvas/.html`.
5. Use `snapshot` when the user needs proof.
## URL shape
```text
http://:/__openclaw__/canvas/index.html
http://:/__openclaw__/canvas/games/snake.html
```
Path mapping:
- `/__openclaw__/canvas/index.html` -> `