Get started with the Experience Canvas Toolbar

This guide walks you through scaffolding, building, and running a minimal app for the Experience Canvas Toolbar location. For the concepts behind this location (the shared editing context, and how node content and design properties are updated), see the Experience Canvas Toolbar overview. For full method signatures, see sdk.experiences in the App SDK reference.

The toolbar location is gated behind a feature flag during rollout. Some accounts may not yet be able to install apps to this location.

Prerequisites

Setup

  • The latest LTS version of Node.js installed on your machine.
  • Be logged in to your Contentful account and have a Contentful space. If you don’t have an account, sign up for it.
  • A space with Experience Orchestration enabled, and at least one experience or fragment to access its canvas.

Knowledge

  • Read and write JavaScript or TypeScript.
  • Be familiar with the Experience Canvas Toolbar concepts — in particular, the distinction between content (Data Assembly) and design properties.

Create your project

The Experience Canvas Toolbar ships as a starter example rather than a CLI-prompted blank template. Scaffold it with the create-contentful-app CLI’s --example flag:

npx create-contentful-app experience-toolbar --example experience-toolbar
Unlike the blank templates (javascript, typescript, vue, vite-react, nextjs), --example <name> pulls a ready-made starter from the examples directory in the contentful/apps repository. The experience-toolbar example lives at examples/experience-toolbar.

The example doesn’t ship an app-definition.json manifest — the toolbar location isn’t a target state you can preconfigure this way, so registering the location happens through the CLI scripts in the next step rather than a checkbox in the app definition form.

Register and run the app

  1. Navigate into the generated project:
cd experience-toolbar
  1. Create an app definition and register the toolbar location:
npm run create-app-definition
This script wraps the same create-app-definition / add-locations flow described in the example’s own README — read it for the full set of prompts.
  1. Start the local development server:
npm start
  1. When you’re ready to install the app to a space, build, upload, and activate it:
npm run build
npm run upload
npm run activate
For the general app definition and installation flow shared by all locations, see Create a custom app.

Read the canvas selection

Once installed, open an experience or fragment in the editor with your app assigned to the toolbar location. The toolbar can read what’s currently selected on the canvas through the Selection API:

import { useSDK } from '@contentful/react-apps-toolkit';
import { useEffect, useState } from 'react';
const Toolbar = () => {
const sdk = useSDK();
const [selection, setSelection] = useState(sdk.experiences.experience.selection.get());
useEffect(() => {
return sdk.experiences.experience.selection.onChange(setSelection);
}, [sdk]);
const selectedNode = selection.nodeId
? sdk.experiences.experience.getNode(selection.nodeId)
: null;
return <div>{selectedNode ? selectedNode.id : 'Nothing selected'}</div>;
};
export default Toolbar;
Use getNode(nodeId) with a known node ID — such as the one returned by the selection — to look up a single node, or getRootNodes() to enumerate the tree from its top-level nodes when you don’t have an ID up front.

Highlight a node on the canvas

The scaffolded example also includes a “Highlight on canvas” button that calls selection.highlight(nodeId) to flash and scroll a node into view — useful for apps that reference a node from outside the canvas and want to point the editor at it.

sdk.experiences.experience.selection.highlight(nodeId, { flash: true, scrollIntoView: true });

Read examples/experience-toolbar’s source for the full implementation.

How the toolbar talks to the editor

Calls you make through sdk.experiences.* are delegated from the toolbar’s ToolbarWidgetRenderer to the host editor through the ToolbarEditorApiRegistry — the editor registers its API with useRegisterToolbarEditorApi, and the toolbar widget’s SDK calls resolve against whatever the editor currently has registered. You don’t need to interact with the registry directly; it’s what makes sdk.experiences.context, the Experience API, the Selection API, and Data Assembly work from inside the toolbar.

Next steps

Cross-cutting APIs such as AgentContext, navigator.openExperience, and taxonomy-scoped access.can checks are out of scope for this guide — they’re deferred to a future phase of the Experience Canvas Toolbar work.