Bring Your Own Components
Studio ships with a small set of default components: Box, Row, Heading, Text, Image, Repeater, and a few more. These defaults demonstrate core registration mechanics and serve as a reference implementation.
For real work, you register your own components. After that, Studio's palette shows your Button, your Card, your Hero alongside the defaults, and authors compose pages with the components your design system already provides.
The Model in One Diagram
You declare a schema (prop names, types, defaults, validation, help text). Studio uses it to render the palette tile, the right-panel form, and the data picker. Your React component runs unchanged: Studio just feeds it the right props at render time. This separation means your component stays framework-agnostic; only the schema needs to understand Studio's UI contracts.
What You Get for Registering
| Surface | What appears |
|---|---|
| Left palette | A tile labelled with your displayName, with your thumbnailUrl (rendered when the component declares a section; user-registered components default into the "Registered Components" section) |
| Canvas | Your component renders inline with the right props bound |
| Right panel — Settings | Each prop gets a form field (typed input, dropdown, link picker, image picker) |
| Right panel — Data | Each prop has a "bind to data" chip that opens the data picker |
| Right panel — Design | If you declared styles, style controls appear here |
| Layers panel | Your component shows by displayName in the layer tree |
What's in This Chapter
| Page | Covers |
|---|---|
| Registering components | The three register APIs: registerComponent, registerComponents, registerLazyComponent |
| Component schema | The schema shape: every field, every prop type |
| Default data | What renders when an author drops a component before binding anything |
| Optimizing load | Lazy registration, Suspense, bundle impact |
| Design tokens | Map your design system's tokens so Studio's controls match brand |
| Studio CLI | csdx plugin for scripted component registration, Figma sync, token import |
| Figma → Studio (copy/paste) | The author flow: paste a Figma frame into the canvas |
| Figma → Studio (generate) | The agentic CLI: generate React components from Figma into your project |
| Testing your components | Preview in isolation, validate prop changes |
| Publishing the library | Share your component library across multiple Studio projects |
The Minimum to Get Started
A registered Button, end-to-end:
// src/lib/studio-components.ts
import { registerComponent } from "@contentstack/studio-react";
import { Button } from "@/components/Button";
import buttonIcon from "@/assets/icons/button.svg";
registerComponent({
type: "Button",
displayName: "Button",
thumbnailUrl: buttonIcon,
component: Button,
props: {
label: { type: "string", defaultValue: "Click me" },
href: { type: "href", defaultValue: "#" },
},
});Import that file once at app boot (alongside @/lib/contentstack) and Button appears in Studio's palette under Registered Components.
Order of Operations Matters
registerComponent must run before the canvas iframe loads, otherwise Studio doesn't see your components in the palette. The safest place is a shared module imported at app boot. See Troubleshoot → "Registered components don't appear" if they're missing.
Tip Run npx @contentstack/studio-skills install, then ask: "register my Button component as a Studio component". The LLM reads your component file, infers the prop shape, and writes the registry entry for you.