Component Editable Regions A designated area within a webpage that wraps a component, include, or partial so Organization Members can change its values in CloudCannon's Visual Editor and see it re-render in place. Unlike the other Editable Region types, Component Editable Regions need an integration installed for your static site generator.Component Editable Region
Component Editable Regions are not yet available for other SSGs. To request support for your SSG, please get in touch with our friendly support team and include the name and version of the SSG you use.
Many static websites use reusable code components (a.k.a., partials) ranging from a small snippet of HTML, to UI elements like a header, profile card, or an entire page layout.
You can use Component Editable Regions to re-render changes to your components in the Visual Editor. They are also required to edit Text or Image Editable Regions nested inside a component. Let's cover how to define one.
Nested text or image values
To avoid A designated area within a webpage where Organization Members can modify text content directly through CloudCannon's visual editing interface. These regions allow inline text editing without requiring knowledge of HTML or Markdown.data-prop misconfiguration errors, it is best practice to define your Editable Regions from the root of your file first (i.e., from parent elements to child elements). If you want to edit text or image values in a component using the Visual Editor, you should define your Component Editable Region on the parent element before TextText Editable Region
Install the integration for your SSG#
Unlike other types of Editable Region, Component Editable Regions need an integration, because CloudCannon re-renders your components in the browser rather than on a build server. Astro and Eleventy install an NPM package, Hugo installs a Hugo module, and sites built with React, Vue, or Svelte add a root component to your layout. You only need to do this once per Site. The @cloudcannon/editable-regions NPM package requires Node 20.19 or later.
Astro
Install the NPM package, then add the Editable Regions integration to your Astro configuration file.
npm install @cloudcannon/editable-regionsimport editableRegions from "@cloudcannon/editable-regions/astro-integration";
import { defineConfig } from "astro/config";
export default defineConfig({
integrations: [editableRegions()],
});Eleventy
Install the NPM package, then add the Editable Regions plugin to your Eleventy configuration file.
npm install @cloudcannon/editable-regionsimport editableRegions from "@cloudcannon/editable-regions/eleventy";
export default function (eleventyConfig) {
eleventyConfig.addPlugin(editableRegions);
return {
dir: { input: "src", includes: "_includes", output: "_site" },
};
}After every build, the plugin writes a register-components.js file into your output directory. Import it from your layout, inside the <body> element.
<script>
if (window.inEditorMode) {
import("/register-components.js").catch((error) => {
console.warn("Failed to load CloudCannon component registration:", error);
});
}
</script>Hugo
Hugo uses a Hugo module rather than an NPM package. Install the module, add it to your Hugo configuration file, then include the Editable Regions partial in the <head> element of your base layout.
hugo mod get github.com/CloudCannon/editable-regions@<version>[module]
[[module.imports]]
path = "github.com/CloudCannon/editable-regions"
version = "<version>"{{ partial "editable-regions" . }}JavaScript frameworks
Install the NPM package, then wrap your routed page content in the EditableRegions component, in your root layout.
Sites built with React, Vue, or Svelte, including Next.js, Nuxt, and SvelteKit, need the EditableRegions component for every type of Editable Region, not just Component Editable Regions.
npm install @cloudcannon/editable-regionsimport { EditableRegions } from "@cloudcannon/editable-regions/react";
export default function RootLayout({ children }) {
return (
<html lang="en">
<body>
<EditableRegions tag="main">{children}</EditableRegions>
</body>
</html>
);
}Import EditableRegions from @cloudcannon/editable-regions/react, /vue, or /svelte, depending on your framework.
Your SSG may need more than this to build in the Visual Editor. For Astro framework renderers, Eleventy's includeWith tag, Hugo module vendoring and version requirements, Nuxt's custom element setting, and static export settings for Next.js, Nuxt, and SvelteKit, please read our documentation on configuring Component Editable Regions. You can also visit CloudCannon's GitHub repository for the Editable Regions NPM package.
Register your components#
Registering a component tells CloudCannon which component a data-component value refers to, and that it should be bundled for client-side use in the Visual Editor. Astro and the JavaScript frameworks need you to register each component by name. Eleventy and Hugo work out the name from your include and partial names, so they have no registration step.
Astro
Create a registration file for your components, then import it from your layout, inside the <body> element.
If you use .astro component files, even if you have React components nested in them, import { registerAstroComponent } in your registration script. Here's an example for the CTA component.
import { registerAstroComponent } from '@cloudcannon/editable-regions/astro';
import '@cloudcannon/editable-regions/astro-react-renderer';
import CTA from '../components/CTA.astro';
// Register your components
registerAstroComponent('cta', CTA);This import is only necessary if you use React components nested inside your Astro components. For Svelte or Vue components, import @cloudcannon/editable-regions/astro-svelte-renderer or @cloudcannon/editable-regions/astro-vue-renderer instead.
If you use .tsx or .jsx component files, import { registerReactComponent } instead.
import { registerReactComponent } from '@cloudcannon/editable-regions/react';
import MyComponent from './MyComponent.jsx';
registerReactComponent('my_component', MyComponent);Eleventy
There is no registration step. CloudCannon resolves component names the same way your templates resolve includes, so {% include "cta" %} matches data-component="cta".
The plugin you added in the previous step copies your includes into the registration script it writes after every build.
Hugo
There is no registration step. CloudCannon resolves component names as partial names, so data-component="cta" and data-component="cta.html" both render layouts/partials/cta.html.
JavaScript frameworks
Register your components from a file that only runs in the browser, such as a client component in Next.js or a client plugin in Nuxt.
import { registerVueComponent } from "@cloudcannon/editable-regions/vue";
import CTA from "../components/CTA.vue";
export default defineNuxtPlugin(() => {
if (window.inEditorMode) {
registerVueComponent('cta', CTA);
}
});Import registerReactComponent from @cloudcannon/editable-regions/react or registerSvelteComponent from @cloudcannon/editable-regions/svelte for those frameworks.
Components in layout files#
Components use templating to reference structured data keys. Layout files then reference a component file. At build time, CloudCannon populates the component with the correct values and outputs it to the layout's HTML webpage.
Let's take a look at an example.
This file is a blog post, containing the cta object in the front matter, and the structured data keys description, link, buttonText, and buttonColor.
---
title: 'First post'
author: 'C. Kent'
heroImage: '../../assets/blog-banner.jpg'
heroImageTitle: 'Blog gradient'
heroImageAlt: 'An eye-catching color gradient banner.'
cta:
description: "Need a little more help? Send a message to our friendly support team."
link: "https://cloudcannon.com/support/"
buttonText: "Send a message"
buttonColor: "#034AD8"
---
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Vitae ultricies leo integer malesuada nunc vel risus commodo viverra.Here is an excerpt from our blog layout file, containing a call-to-action component called CTA at the bottom of every blog post.
---
import CTA from '../components/CTA.astro';
---
<html lang="en">
<body>
<main>
<article>
<!-- Blog HTML here -->
</article>
<CTA {...Astro.props.cta} />
</main>
</body>
</html>The <CTA> component uses structured data in the front matter of the files in the Blog Collection.
Finally, here's our component layout file, which contains HTML for the component and templating to populate elements with values from each blog file.
---
const { description, link, buttonText, buttonColor } = Astro.props;
---
<p>{description}</p>
<a href={link}>
<button style={`background-color: ${buttonColor}`}>{buttonText}</button>
</a>Together, these files output a webpage that looks like this:

In this example, the <CTA> component uses the properties in the cta object in each blog post. We can add a Component Editable Region to our layout file to enable the Visual Editor to re-render any changes made with the Data Panel or sidebar.
First you need to import the component registration file you made earlier with a <script> HTML element. The <script> element should go inside the <body> element of your layout, which could be a different file depending on how your Site is structured (e.g., you may have a base layout file that all your other layouts reference). When you import the component registration file, you can also add instructions to check if your browser window is in Editor Mode (i.e., your webpage is open in CloudCannon's Visual Editor) and add an error warning.
Next, since the <CTA> component lacks an appropriate parent DOM element, you should wrap it in the <editable-component> web component. Our Component Editable Region also needs a data-prop to define where our component data is stored which, in this case, will be the cta front matter object in our blog post.
Finally, you need to add the data-component HTML attribute to define which registered component we are using which, in this case, is also called cta.
Here's what our blog layout code should look like:
<html lang="en">
<body>
<script>
if (window.inEditorMode) {
import("../scripts/register-components.js").catch((error) => {
console.warn("Failed to load CloudCannon component registration:", error);
});
}
</script>
<main>
<article>
<!-- Blog HTML here -->
</article>
<editable-component data-prop="cta" data-component="cta">
<CTA {...Astro.props.cta} />
</editable-component>
</main>
</body>
</html>The <script> element instructs your browser to import the register-components.js file if your webpage is open in the Visual Editor.
The editable-component web component defines a Component Editable Region. The data-prop attribute defines the path to the data we want to edit, and the data-component defines which registered component we are using. In this case, we want to edit the cta structured data key in the blog front matter and use the registered component cta.
If we were to save and rebuild our Site now, the Visual Editor would allow you to re-render the CTA component when you edit values using the Data Panel or sidebar, but would not allow inline editing for the text values description and buttonText. To achieve this, we also need to add Text Editable Regions to the CTA component file.
Here's what our CTA component code should look like:
---
const { description, link, buttonText, buttonColor } = Astro.props;
---
<p data-editable="text" data-prop="description">{description}</p>
<a href={link}>
<button data-editable="text" data-prop="buttonText" style={`background-color: ${buttonColor}`}>{buttonText}</button>
</a>This <p> element contains data-editable="text" and data-prop="description" to define a Text Editable Region.
This <button> element contains data-editable="text" and data-prop="buttonText" to define a Text Editable Region.
Once we save and rebuild our Site, CloudCannon will show a yellow Editable Region box around all the content inside the <CTA> component in the Visual Editor. There are also two Text Editable Regions around the description and button text.

CloudCannon will show an edit icon in the top right of the Component Editable Region. Clicking the edit icon opens a Data Panel with inputs for all four structured data keys in the component: description, link, buttonText, and buttonColor. The edit icon only appears if your Component Editable Region has a data-prop or data-prop-* HTML attribute.
Common errors#
If you accidentally misconfigure your Editable Regions, CloudCannon will replace them in the Visual Editor with a red Error Card headed Failed to render component, or Failed to render component: [Component Name] if your component fails to render, followed by a message describing the problem.

Here are a few common errors you might encounter with Component Editable Regions:
- You did not define the
data-componentHTML attribute. - You reference a component that does not exist, or has not been registered.
- Your component throws an error while rendering, or does not return HTML.
In the next step of this guide, we'll cover how to define Editable Regions for complex arrays.