# Canvas

> Present HTML on connected MarketingClaw node canvases, navigate/eval/snapshot, and debug canvas host URLs.

- Skill: `promisingcoder/canvas` (Agent Skill)
- Install (CLI): `npx skillmds@latest add promisingcoder/canvas`
- Raw SKILL.md: https://api.skillmd.com/api/skills/promisingcoder/canvas/raw
- Safety review: PASS (external: skill-scanner PASS, skillspector PASS)
- Works with: Claude Code, Claude.ai, OpenAI Codex
- Category: Web & Frontend
- Author: promisingcoder (https://skillmd.com/u/promisingcoder)
- Updated: 2026-08-19
- Page: https://skillmd.com/skills/promisingcoder/canvas

---


# 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: `$MARKETINGCLAW_CONFIG_PATH` or `~/.marketingclaw/marketingclaw.json`.

```json
{
  "plugins": {
    "entries": {
      "canvas": {
        "config": {
          "host": {
            "enabled": true,
            "root": "~/.marketingclaw/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: `/__marketingclaw__/canvas/<file>.html`.
5. Use `snapshot` when the user needs proof.

## URL shape

```text
http://<gateway-host>:<gateway.port>/__marketingclaw__/canvas/index.html
http://<gateway-host>:<gateway.port>/__marketingclaw__/canvas/games/snake.html
```

Path mapping:

- `/__marketingclaw__/canvas/index.html` -> `<canvas host root>/index.html`
- `/__marketingclaw__/canvas/games/snake.html` -> `<canvas host root>/games/snake.html`

## Troubleshooting

- Node sees localhost but is remote: fix `gateway.bind` or 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 `liveReload` and file write under root.

