Note: Studio is currently part of an Early Access Program and may not be available to all users. Contact the Contentstack support team; they will coordinate with the appropriate stakeholders to review eligibility.
Studio includes a built-in library of components (e.g., text, images, containers) for building pages. However, most real-world projects require custom UI components to reflect brand identity, support specific logic, or enable advanced user interactions.
This guide shows how to create, register, and enhance your own React components so they appear in the Registered Components panel for drag-and-drop use in Studio.
To register a component:
Here’s a basic example, a Heading 2 (<h2>) component.
function H2() {
return <h2>I am a heading</h2>;
}
Import registerComponents and call it with your component definition:
import { registerComponents } from "@contentstack/studio-react";
function H2() {
return <h2>I am a heading</h2>;
}
registerComponents([
{
type: "h2", // Unique internal name (one word, lowercase)
component: H2,
},
]);
After registering, the component appears in Registered Components in Studio.
Most components need props so users can change their content or behavior in the Studio.
Example: To make the heading text customizable.
interface H2Props {
text: string;
}
function H2(props: H2Props) {
const { text } = props;
return <h2>{text}</h2>;
}
registerComponents([
{
type: "h2",
component: H2,
props: {
text: {
type: "string", // Prop type
defaultValue: "Hello World", // Initial value
},
},
},
]);
Now, you can edit the text prop via the right-hand properties panel in Studio.
To enable inline editing (Live Edit) from CMS-bound content:
import { CslpTag } from "@contentstack/studio-react";
interface H2Props {
text: string;
$text: CslpTag; // Live Edit tag type
}
function H2(props: H2Props) {
const { text, $text } = props;
return <h2 {...$text}>{text}</h2>;
}
By default, Studio wraps your component in a <div> to enable editing. You can change or disable this behavior. When you disable it, you have to pass the studio attributes manually to the component to enable editing in the canvas.
The below example shows how you can wrap a component with a section tag instead of div:
registerComponents([
{
type: "h2",
component: H2,
wrap: "section",
},
]);
If you disable wrapping, you must manually apply Studio editing attributes.
import { StudioAttributes, CslpTag } from "@contentstack/studio-react";
interface H2Props extends StudioAttributes {
text: string;
$text: CslpTag;
}
function H2(props: H2Props) {
const { text, $text, studioAttributes } = props;
return (
<h2 {...studioAttributes} {...$text}>
{text}
</h2>
);
}
registerComponents([
{
type: "h2",
component: H2,
wrap: false, // Disable default wrapper
},
]);
Note: These attributes are required for Studio functionality. Omitting them can result in errors during component interaction.
To register a component without displaying it in the Studio library:
registerComponents([
{
type: "h2",
component: H2,
hideFromComponentList: true,
},
]);
Make your components easier to identify and use by adding:
registerComponents([
{
type: "h2",
component: H2,
displayName: "Heading 2",
thumbnailUrl: "https://example.com/heading2.png",
},
]);
By default, all registered components appear under Registered Components. You can organize them into custom sections:
registerComponents([
{
type: "h2",
component: H2,
displayName: "Heading 2",
thumbnailUrl: "https://example.com/heading2.png",
sections: "Custom Headings", // Your own section name
},
]);
Define default styling or apply tokens from your design system:
registerComponents([
{
type: "h2",
component: H2,
styles: {
default: {
displayName: "Body",
defaultStyles: {
backgroundColor: "red",
},
},
},
},
]);
Follow these tips for maintainable and user-friendly components:
Custom component registration empowers your team to extend Studio with reusable, brand-aligned UI elements tailored to your project’s needs. By combining standard React patterns with Studio’s powerful visual interface, you can deliver consistent, editable, and scalable components, without sacrificing control or flexibility.
Whether you’re adding a simple heading or integrating deeply with your design system, registered components ensure your page-building experience remains structured, intuitive, and developer-friendly.