Recent searches

in

Visual Data Previews with React

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.

The CloudCannon React Connector is a higher-order component that wraps the sequence described in our documentation on using Visual Data Previews with vanilla JavaScript. It listens for CloudCannon's events, calls enableEvents(), reads the latest data with value(), and re-renders your page component with it.

The connector targets the Next.js Pages Router and the pageProps shape that router supplies. It has no App Router integration, so on an App Router project, write the event handling yourself: please read our documentation on using Visual Data Previews with vanilla JavaScript.

For what your Site needs before a preview will run, please read our documentation on what Visual Data Previews are.

Installation#

This package targets the deprecated v0 Visual Editor API. For new Sites, please read our documentation on initializing the Visual Editor API.

The React Connector lists React 17 as a dependency, not a peer dependency.

The package declares react: ^17.0.2 under dependencies and declares no peer dependencies, so installing it in a project on React 18 or later adds a second copy of React to your node_modules and your bundle. Check what this installs before adding it to an existing project.

Shell
Copied to clipboard
npm i @cloudcannon/react-connector

Setting up the connector#

Wrap your Next.js app component with CloudCannonConnect in pages/_app.jsx. CloudCannonConnect() returns a new component class each time it runs, so memoize the result on Component to stop React remounting your page on every navigation.

JSX
Copied to clipboard
import { useMemo } from 'react';
import { CloudCannonConnect } from '@cloudcannon/react-connector';

export default function App({ Component, pageProps }) {
  const AppComponent = useMemo(() => CloudCannonConnect(Component), [Component]); 
  return <AppComponent {...pageProps} />;
}

Keying useMemo on Component keeps the generated class stable between renders.

The connector also reads window.CloudCannon when your component mounts, as a fallback for mounting after cloudcannon:load has already fired. If other code on your page calls useVersion('v1'), CloudCannon reassigns that global to the v1 object, which has no enableEvents(), and the fallback throws. Pass true as the second argument, useVersion('v1', true), to get the v1 object without reassigning the global. For more information, please read our documentation on initializing the Visual Editor API.

Reading the data in your components#

The connector does not spread the latest values into your component's top-level props. It replaces page.data, so your page component reads its content from props.page.data.

JSX
Copied to clipboard
export default function HomePage({ page }) {
  return <h1>{page.data.title}</h1>; 
}

The connector replaces page.data with the latest values after every change. Supply page.data in your pageProps as well: the connector renders from it before CloudCannon sends anything, and falls back to an empty object when it is missing.

Options#

CloudCannonConnect() takes an optional second argument.

processProps — Function#

Runs over the data before the connector passes it to your component as page.data. Receives the latest data and returns what your component should receive. Defaults to passing the data through unchanged.

valueOptions — Object#

Passed through to value() each time the connector reads the latest data.

JSX
Copied to clipboard
const AppComponent = useMemo(
  () => CloudCannonConnect(Component, { processProps: (data) => data.fields }),
  [Component]
);

Getting help#

If the connector does not behave as described, contact support with your Site name, the React and Next.js versions your project uses, and what you expected to happen. You can also raise an issue on the GitHub repository.

Related Resources

Open in a new tab