Recent searches

in

Build a custom interface

Render a custom drawing interface that only appears inside the Visual Editor.

Now that we've detected the Visual Editor and have the API, we can render our own interface. The Doodle Gallery brings its own UI: a canvas to draw on, a caption field, and a submit button. Because we gated the component on inCloudCannonEditor in the previous step, this interface only renders inside the Visual Editor.

A screenshot of the custom drawing interface inside the Visual Editor, with a blank canvas on the left and caption and submit controls on the right.

Render whatever markup your interface needs — CloudCannon doesn't require any particular wrapper or class.

TypeScript
Copied to clipboard
return (
  <div className="cloudcannon-visual-editor-component"> 
    <h1>Why not draw something?</h1>

    <DoodleCanvas
      canvasRef={canvasRef}
      finishDraw={(newPixels: CoordArray) => { setSavedPixels([...savedPixels, [...newPixels]]); }} 
    ></DoodleCanvas>

    <label htmlFor="caption">Caption for the new image (required)</label>
    <input type="text" id="caption" onInput={(e) => { setCaption(e.currentTarget.value); }} /> 

    <button type="button" disabled={!!currentStateMessage || !caption} onClick={submit}>Add to the gallery</button> 
  </div>
);

The Doodle Gallery styles this wrapper with its own striped background in main.css. The class name isn't special to CloudCannon — use whatever markup and styling you like.

DoodleCanvas is a plain React component that captures the drawing and hands the strokes back through finishDraw. None of its code touches the Visual Editor API.

Capture the caption a Team Member types. We'll save it alongside the image.

The submit button calls our submit() function, which we'll cover in the next steps of this guide. It's disabled until a Team Member enters a caption, and stays disabled while a save is in progress, so they can't start a second save before the first finishes.

The Doodle Gallery renders this component on its homepage. In Astro, that means importing it and rendering <Doodler client:load /> — the client:load directive hydrates the component in the browser, where it can reach the Visual Editor API. Other frameworks and SSGs each have their own way to mount a client-side component; whichever you use, the only requirement is that your integration runs in the browser.

ASTRO
Copied to clipboard
---
import { Doodler } from "../components/doodle.tsx"; 
---

<Doodler client:load /> 

Import the component into the page where you want the tool to appear.

Render it with client:load so the component hydrates in the browser.

Bringing your own UI like this gives you complete control over the experience. If instead you want to reuse CloudCannon's native editing surfaces, the Visual Editor API can also open its own Data Panels and make page elements directly editable.

In the next step of this guide, we'll start building the submit function, beginning by uploading the finished doodle as an image.

Build custom Visual Editor integrations (4/7)
Build a custom interface
Open in a new tab