Recent searches

in

Detect the Visual Editor and initialize

Detect the Visual Editor and initialize the Visual Editor API before your integration runs.

Custom integrations built with the Visual Editor API should only appear inside the Visual Editor, never on the live website.

In the Doodle Gallery example, the gallery of doodles appears as the first item on the webpage when you view it through your internet browser.

A screenshot of the Doodle Gallery example in a web browser shows that only the Gallery, not the drawing canvas, is visible.

The drawing canvas only appears at the top of the webpage when loaded in the Visual Editor.

A screenshot of the Visual Editor shows the Doodle Gallery's drawing tool at the top of a webpage preview, with a blank canvas, a caption field, and an Add to the gallery button.
A screenshot of the Doodle Gallery section showing two submitted doodles, each with a caption, rendered from the data file.

When you open a file in the Visual Editor, CloudCannon injects a script that sets window.inEditorMode to true in the document before loading it into the iframe, and leaves it undefined everywhere else. We can use this flag to keep custom integrations inside the Visual Editor. Once we know we're in the Visual Editor, we can request the API with window.CloudCannonAPI.useVersion('v1', true).

If you are writing in TypeScript, you can get type checking and autocomplete with the Visual Editor API.

The Doodle Gallery imports the API's types from the @cloudcannon/visual-editor-api package. Because the types are only used at build time, install it as a dev dependency:

Shell
Copied to clipboard
npm install --save-dev @cloudcannon/visual-editor-api
TypeScript
Copied to clipboard
import { useState, useRef, useEffect } from 'react';
import type { CloudCannonVisualEditorAPIV1, CloudCannonVisualEditorWindow } from '@cloudcannon/visual-editor-api'; 

declare const window: CloudCannonVisualEditorWindow & { inEditorMode: true | undefined } 

export function Doodler() {
  const apiRef = useRef<CloudCannonVisualEditorAPIV1 | undefined>(undefined); 
  const canvasRef = useRef<HTMLCanvasElement>(null);
  const [inCloudCannonEditor, setInCloudCannonEditor] = useState<boolean>(false);

  useEffect(() => {
    if (!window.inEditorMode) { 
      return;
    }
    setInCloudCannonEditor(true);

    const initApi = () => {
      apiRef.current = window.CloudCannonAPI?.useVersion('v1', true); 
    };

    if (window.CloudCannonAPI) { 
      initApi();
      return;
    }

    document.addEventListener('cloudcannon:load', initApi, { once: true }); 
    return () => document.removeEventListener('cloudcannon:load', initApi);
  }, []);

  if (!inCloudCannonEditor) {
    return undefined; 
  }

  // ...render the drawing tool
}

Import the API and window types from the @cloudcannon/visual-editor-api package.

Declare window with CloudCannon's types so inEditorMode and CloudCannonAPI are typed.

Hold the API Object in a useRef so it persists across re-renders, ready for whenever a Team Member submits. useRef(undefined) touches no browser globals, so it's safe during a server-side build.

Only run inside the Visual Editorwindow.inEditorMode is true there and undefined on the live Site — and bail out early everywhere else.

Request v1 of the API with useVersion('v1', true). The true keeps the API Object off the global window.CloudCannon, so it won't clash with integrations using another API version.

If window.CloudCannonAPI already exists, initialize immediately.

Otherwise wait for the cloudcannon:load event, which CloudCannon dispatches after setting window.CloudCannonAPI. { once: true } and the cleanup remove the listener once it fires or the component unmounts.

Render nothing outside the Visual Editor, so the tool never appears for site visitors.

The Visual Editor API is available on window.CloudCannonAPI whenever a file is open in the Visual Editor. The Doodle Gallery initializes it inside a React useEffect, but the same approach works in any framework — the only requirement is that the code runs in the browser, not during a server-side build.

Depending on how your integration loads, window.CloudCannonAPI may not exist yet when your code first runs.

Before the Doodle Gallery integration performs any other actions, it checks whether the webpage is already running in the Visual Editor, then initializes the Visual Editor API. If not, it waits for the cloudcannon:load event, which CloudCannon dispatches after setting window.CloudCannonAPI. Because the API Object lives in a useRef, it's ready whenever a Team Member later submits a doodle, no matter which path initialized it.

In the next step of this guide, we'll render the custom interface Team Members use to draw a doodle.

Build custom Visual Editor integrations (3/7)
Detect the Visual Editor and initialize
Open in a new tab