@contentstack/studio-react
v2.0.0
Published
Official React SDK for Contentstack Studio. Build powerful, composable content experiences with pre-built React components, hooks, and utilities. Seamlessly integrate with Contentstack's headless CMS to create dynamic, scalable applications with TypeScrip
Readme
Studio React
A React library for building and rendering studio components with Contentstack's Visual Builder. This package provides React components, hooks, and utilities for creating dynamic, editable content experiences.
Prerequisites
Contentstack Delivery SDK. You can follow the instructions to setup the SDK.
Installation
npm install @contentstack/studio-reactPeer Dependencies
This package requires React 16.0.0 or higher:
{
"peerDependencies": {
"react": ">=16.0.0",
"react-dom": ">=16.0.0"
}
}Quick Start
Basic Usage
import { StudioComponent, useCompositionData } from "@contentstack/studio-react";
// Initialize the SDK
studioSdk.init({
stackSdk: Stack, // Contentstack Delivery SDK
cslp: {
appendTags: true,
},
});
function MyApp() {
const { specOptions, isLoading, error } = useCompositionData({
composableUid: 'your-composition-uid',
});
if (isLoading) return <div>Loading...</div>;
if (error) return <div>Error: {error.message}</div>;
return <StudioComponent specOptions={specOptions} />;
}Deciding render, 404, or 5xx
A resolved fetch always means render. Every "there is no page at this URL" outcome rejects, so the decision comes from the error, not from a flag on the result:
// The three ids that mean "no page at this URL". They are also available as
// `ComposableStudioErrors` from `@contentstack/studio-client`, if you depend on
// that package directly.
const NOT_FOUND = new Set([
"COMPOSITION_NOT_FOUND",
"COMPOSITION_NOT_FOUND_BY_URL",
"PREVIEW_ENTRY_NOT_FOUND",
]);
try {
specOptions = await sdk.fetchCompositionData({ url }, { locale });
} catch (error) {
if (NOT_FOUND.has(error?.id)) notFound(); // no page at this URL
throw error; // network / auth / server → 5xx
}Two mistakes are worth calling out, because both are easy to write and neither fails loudly.
Do not gate rendering on hasTemplate. It is false for every freeform
composition — one with no connected content type — so if (!specOptions.hasTemplate)
notFound() returns 404 for every freeform page you publish, no matter which environments
you deploy it to. Use spec.compositionEntry.connected_content_type if you need to know
whether a composition is connected.
Do not map every error to 404. A bare catch { notFound() } turns an expired delivery
token, a delivery-API outage or a network blip into a 404, which tells search engines your
live pages are gone.
Full rule, including which ids mean what:
studio-client README. hasSpec and
hasTemplate are deprecated and will be removed in a future major.
Registering Components
To register components, use the registerComponent function:
import { registerComponent } from "@contentstack/studio-react";
function MovingBanner({ children, ...rest }) {
return <marquee {...rest}>{children}</marquee>;
}
registerComponents([
{
name: "moving-banner",
displayName: "Moving Banner",
component: MovingBanner,
props: {
children: {
type: "slot",
displayName: "Content",
}
}
},
])