Skip to content

Visual Edit & Live Preview

Visual edit — click any element in the preview to change text, colors, and styles instantly without AI tokens

Doable's "visual edit" feature lets you point at any element in the live preview and change it — text, color, padding, image — without writing code or spending AI tokens. Behind the scenes, your edits are translated to AST patches and applied directly to the source files.

Turning it on

In the editor toolbar above the preview, click the cursor icon (or press V). The preview now shows a hover outline; clicking an element opens the inspector.

What you can edit visually

  • Text content — double-click and type.
  • Inline styles — color, background, padding, margin, border-radius, font-size.
  • Tailwind classes — pick from a class palette filtered to the relevant property.
  • src / alt for images.
  • href for links.

For anything more structural (adding a new component, restructuring layout), drop into the chat and describe what you want.

How it works

  1. The preview iframe loads with the visual edit bridge injected.
  2. When you click an element, the bridge sends the element's source location (file + line + column) to the parent (Doable editor).
  3. The inspector shows the relevant properties.
  4. When you confirm a change, the editor sends:
    POST /direct-save/:projectId
    { "filePath": "...", "patches": [...] }
    
  5. The API parses the file with @babel/parser, applies the patches via @babel/types, prints back with recast (preserving formatting), and writes the file.
  6. Vite HMR picks up the change. You see the result instantly.

The bridge script is at services/api/src/visual-edit-bridge-inline.ts. The direct-save handler is at services/api/src/direct-save/.

Why "no AI tokens"?

Visual edits go through a deterministic AST patch — no model in the loop. Result:

  • Free (no token cost).
  • Instant (no model latency).
  • Predictable (same input → same output).

Use the chat for anything the inspector can't express; use the inspector for the dozens of small tweaks per session.

Components vs DOM elements

Doable inspects the React element, not the rendered DOM. So when you click a <Hero /> component instance, the inspector shows the props you can override (title, subtitle, imageSrc) and writes them in the parent component's JSX.

Limitations

  • Works best on Vite + React + Tailwind projects (the supported template stack).
  • Components in node_modules aren't editable visually — switch to chat or the code editor.
  • If you've heavily customized the build (renamed Vite to webpack, swapped Tailwind for vanilla CSS), the AST patches may not apply — fall back to chat.

Debugging

If clicks don't show the inspector:

  • Open the browser devtools, look for [visual-edit-bridge] console logs.
  • Make sure the project's HTML response goes through the API's /preview/ route — direct localhost links bypass the injection.
  • Check that the project's components emit data-loc attributes (added by the Vite plugin Doable injects automatically; absent from very old projects).