Deep Dive: Canvas & A2UI Integration Patterns for Advanced Workflows
Deep Dive: Canvas & A2UI Integration Patterns for Advanced Workflows
You know what Canvas is. You know A2UI pushes components to a WebView. Now let's talk about what you can actually build with them โ the patterns that turn a lightweight UI panel into a real operational surface for your agent.
Pattern 1: Snapshot-Driven Feedback Loops
The most powerful Canvas pattern isn't displaying content โ it's reading it back. Canvas supports canvas snapshot, which captures the current rendered state as an image. Combined with A2UI pushes, this creates a closed feedback loop:
- Agent pushes a UI surface via
canvas a2ui push - Agent captures a snapshot with
canvas snapshot - Agent analyzes the screenshot (via vision model or pixel inspection)
- Agent updates the surface based on what it sees
# Push a status dashboard
openclaw nodes canvas a2ui push --node mac --jsonl /tmp/dashboard.jsonl
# Capture what's rendered
openclaw nodes canvas snapshot --node mac --format png --max-width 1200
# Agent inspects the result and decides next action
This is particularly useful for validation workflows โ the agent renders a preview, checks it looks correct, and only then proceeds. Think of it as visual unit testing for dynamic content.
When to use this
- Verifying chart/graph rendering before sharing
- Confirming form layouts before presenting to a user
- Debugging A2UI surface updates that aren't rendering as expected
Pattern 2: Multi-Surface Management
A2UI surfaces are identified by surfaceId. While Canvas shows one surface at a time (via beginRendering), you can maintain multiple surfaces in memory and switch between them instantly.
{"surfaceUpdate":{"surfaceId":"tasks","components":[{"id":"root","component":{"Column":{"children":{"explicitList":["header","list"]}}}}]}}
{"surfaceUpdate":{"surfaceId":"metrics","components":[{"id":"root","component":{"Column":{"children":{"explicitList":["title","chart"]}}}}]}}
{"beginRendering":{"surfaceId":"tasks","root":"root"}}
Switch views by sending a new beginRendering with a different surfaceId. The previously rendered surface stays in memory โ switching back is instant because you don't need to re-push components.
Practical example: Agent workspace tabs
Your agent manages three surfaces:
inboxโ incoming messages and notificationsdashboardโ metrics and system healtheditorโ content preview
The agent switches between them based on context. Processing emails? Show inbox. Running a health check? Flip to dashboard. Drafting a reply? Display the editor. One Canvas panel, multiple workspaces.
Pattern 3: Deep Link Agent Triggers
Canvas content can trigger new agent runs via the openclaw://agent?... URL scheme. This turns your Canvas into an interactive control surface where UI elements drive agent actions.
// Button in your Canvas HTML that triggers an agent task
document.getElementById('refresh-btn').addEventListener('click', () => {
window.location.href = 'openclaw://agent?message=Refresh%20dashboard%20metrics';
});
The macOS app intercepts this deep link and (after confirmation) starts a new agent turn with the specified message. This creates a bidirectional loop: the agent controls Canvas, and Canvas controls the agent.
Security note
Deep links prompt for confirmation by default. This is intentional โ you don't want arbitrary web content triggering agent actions. For trusted Canvas content (which only the agent itself writes), this provides a clean feedback mechanism without opening attack surfaces.
Pattern 4: JavaScript Evaluation for Dynamic Content
canvas eval lets the agent run arbitrary JavaScript inside the Canvas WebView. This is more flexible than A2UI pushes for certain workflows:
# Read the current page title
openclaw nodes canvas eval --node mac --js "document.title"
# Inject data into an existing page
openclaw nodes canvas eval --node mac --js "window.updateMetrics({cpu: 42, mem: 78})"
# Query DOM state
openclaw nodes canvas eval --node mac --js "document.querySelectorAll('.task-item').length"
The key difference from A2UI: canvas eval works with any HTML/JS content (not just A2UI surfaces). Navigate Canvas to a local HTML file, then manipulate it with eval. This is ideal for custom dashboards that need richer interactivity than A2UI components provide.
Combining eval with A2UI
You can use both in sequence:
- Push an A2UI surface for the layout
- Use
canvas evalto inject dynamic data or attach event listeners - Use
canvas snapshotto verify the result
Pattern 5: Local File Serving for Rich Content
Canvas serves files from ~/Library/Application Support/OpenClaw/canvas/<session>/ via the openclaw-canvas:// scheme. Your agent can write HTML/CSS/JS files to this directory and navigate Canvas to display them.
# Agent writes a custom dashboard
mkdir -p ~/Library/Application\ Support/OpenClaw/canvas/main/
cat > ~/Library/Application\ Support/OpenClaw/canvas/main/index.html << 'EOF'
<!DOCTYPE html>
<html>
<head><style>body { font-family: system-ui; background: #1a1a1a; color: #e0e0e0; }</style></head>
<body>
<h1>Agent Dashboard</h1>
<div id="content">Loading...</div>
<script>
// Agent will inject data via canvas eval
window.updateContent = (html) => document.getElementById('content').innerHTML = html;
</script>
</body>
</html>
EOF
# Navigate Canvas to the local file
openclaw nodes canvas navigate --node mac --url "/"
Canvas auto-reloads when local files change, so the agent can update the HTML and the panel refreshes automatically. No manual intervention needed.
When local files beat A2UI
- You need CSS animations or complex layouts
- The UI requires third-party JavaScript libraries
- You're building something more app-like than dashboard-like
- You want full control over the rendering pipeline
Pattern 6: Production Workflow โ Monitoring Pipeline
Here's a complete workflow that ties these patterns together. The agent runs a monitoring pipeline every 30 minutes:
- Collect data โ query APIs, check system health, scan inboxes
- Build surface โ push an A2UI dashboard with the results
- Validate โ snapshot the Canvas and verify rendering
- React โ if anomalies are detected, trigger a deep link for investigation
- Archive โ write the snapshot to a log directory for history
The Canvas panel becomes a live operational dashboard that the agent maintains autonomously. The user glances at it when they want โ the agent keeps it current.
Constraints to Know
Before building advanced workflows, understand the boundaries:
- A2UI v0.8 only โ
createSurface(v0.9) is not supported. UsesurfaceUpdate+beginRenderinginstead. - One visible surface โ Canvas shows one surface at a time. Multi-surface is in-memory only.
- Node must be foregrounded โ
canvas.*commands fail withNODE_BACKGROUND_UNAVAILABLEif the app is in the background. - Directory traversal blocked โ Canvas files must live under the session root. No escaping to arbitrary paths.
- No loopback server โ local content uses the custom
openclaw-canvas://scheme, notlocalhost. This means no CORS issues but also no fetch-to-localhost from Canvas content. - Confirmation on deep links โ
openclaw://agent?...triggers a user prompt unless a valid key is provided. Plan for this in automated workflows.
Choosing Your Approach
| Need | Best Tool |
|------|-----------|
| Structured data display | A2UI surfaceUpdate |
| Custom interactive UI | Local HTML + canvas eval |
| Quick text/status | a2ui push --text "..." |
| Visual verification | canvas snapshot |
| User-triggered actions | Deep links (openclaw://agent?...) |
| Dynamic data injection | canvas eval with JS |
Wrapping Up
Canvas and A2UI aren't just display surfaces โ they're a bidirectional interface between your agent and the visual world. The patterns here โ feedback loops, multi-surface management, deep links, eval injection, local file serving โ combine to create workflows that are genuinely interactive, not just "agent pushes text to a panel."
Start with a simple A2UI push. Add a snapshot loop. Then build from there. The Canvas is small by design, but what you can do with it scales as far as your agent's imagination.
Enjoyed this article?
Join the ClawMakers community to discuss this and more with fellow builders.
Join on Skool โ It's Free โ