Recent searches

in

Visual Data Previews with vanilla JavaScript

Last modified: October 14th, 2026

On this page

The v0 Visual Editor API is deprecated.

CloudCannon continues to maintain the v0 API and fix critical bugs, but it receives no new features or further development. Existing Sites relying on this configuration will keep working. For new Sites, we recommend v1, the current version of the Visual Editor API.

A live preview in vanilla JavaScript comes down to four steps: listen for cloudcannon:load, call enableEvents(), listen for cloudcannon:update, and read the latest data with value(). The sections below walk that sequence, and the separate job of writing values back into the file with set(). For the event model behind it, and for what your Site needs before any of it runs, please read our documentation on what Visual Data Previews are.

Listening for the load event#

Listen for cloudcannon:load on document and take the CloudCannon object from the event.

JavaScript
Copied to clipboard
document.addEventListener('cloudcannon:load', function (e) {
  onLoad(e.detail.CloudCannon); 
});

Note the singular detail. e.details is undefined.

A script that starts after the event has already fired would wait on a listener that never runs, so check for the v0 object on window as well. Test for enableEvents rather than the object alone: window.CloudCannon holds whichever version was installed last, and a useVersion('v1') call elsewhere on your page replaces it. For more information, please read our documentation on initializing the Visual Editor API.

JavaScript
Copied to clipboard
document.addEventListener('cloudcannon:load', function (e) {
  onLoad(e.detail.CloudCannon);
});

if (window.CloudCannon?.enableEvents) { 
  onLoad(window.CloudCannon);
}

Covers a script that loads late, such as one imported dynamically after the page has finished loading.

Turning on update events#

Your load handler has one more job: call enableEvents() once, or cloudcannon:update never fires.

JavaScript
Copied to clipboard
function onLoad(CloudCannon) {
  CloudCannon.enableEvents();
}

With events enabled, add the update listener.

JavaScript
Copied to clipboard
document.addEventListener('cloudcannon:update', function (e) {
  render(e.detail.CloudCannon);
});

Reading the latest data#

value() returns a promise that resolves to the file's structured data as an object, or as an array where the file's top-level value is a list. For a page with front matter, that is the front matter, and it does not return the file's body. The published types declare the return as Promise<string>, but value() resolves a parsed value rather than a JSON string.

Pairing value() with the update event is what produces a live preview: the event tells you something changed, and value() tells you what the data is now.

JavaScript
Copied to clipboard
async function render(CloudCannon) {
  const data = await CloudCannon.value(); 
  document.getElementById('title').textContent = data.title;
}

Resolves to a parsed value, not a JSON string, even though the published types declare Promise<string>.

Writing a value back#

set() writes a value into the file you have open, which is useful for custom controls you add to the page. CloudCannon claims the editing lock for the file before applying the change, and the result behaves the same as editing that field in the Visual Editor sidebar. If the lock cannot be claimed, the write is dropped without an error reaching your code, so do not treat a resolved call as proof the value was saved.

JavaScript
Copied to clipboard
CloudCannon.set('title', 'A new title');

The complete preview loop#

The load handler enables events and performs the first render. The update handler re-renders. The window.CloudCannon?.enableEvents check covers a script that started late. You can register the update listener before or after enableEvents() runs, because neither the listener nor the call depends on the other having happened first.

JavaScript
Copied to clipboard
async function render(CloudCannon) {
  const data = await CloudCannon.value();
  document.getElementById('title').textContent = data.title;
}

function onLoad(CloudCannon) {
  CloudCannon.enableEvents(); 
  render(CloudCannon); 
}

document.addEventListener('cloudcannon:load', (e) => onLoad(e.detail.CloudCannon));
document.addEventListener('cloudcannon:update', (e) => render(e.detail.CloudCannon)); 

if (window.CloudCannon?.enableEvents) {
  onLoad(window.CloudCannon);
}

Without this call, the update listener below never fires.

The load event does not carry content, so render once here to populate the page with the current values.

You can register this listener before or after enableEvents() runs.

Related Resources

Open in a new tab