Skip to main content

Bring your own data

Component Data is how data that isn't in Contentstack becomes bindable. Anything your app can get hold of counts, however it got it: an analytics view count, a price from a pricing service, a signed-in user, a cart total, a value you computed in the component above. You pass it in code, and from then on an author binds to it in the Data Picker exactly as they bind a field from an entry.

That is the point of it. A section or a template is not limited to the content in your stack. Studio binds whatever you hand it.

The example on this page is the Post byline section in the Blog project. You add a ViewCount component to it that shows a view count. ViewCount, viewCount, 100 and 1204 are example values, so replace them with your own component, key and numbers.

In Studio, the section has the sample data { "viewCount": 100 }. On /blog/ai-101, your app passes the live count, 1204.

To pass data another way, see Choose the right way to pass your data.

Prerequisites​

  • Open a template or section on the canvas, such as the Post byline section.
  • Turn on Enable Freeform Feature for the project, so you can type sample data.
  • Render templates with StudioComponent from @contentstack/studio-react.
  • A component with registered props. A component with none has nothing to bind, and Settings says "No properties available for the selected component."

Choose the right way to pass your data​

Studio has four ways to give components data from your own code. They differ by how far the data reaches and by who binds it, and the first two both land in the Data Picker under Component Data.

WayScopeWho binds itUse it when
Component Data. data on StudioComponent.The whole Template or SectionAn author, under Component Data in the Data PickerA value isn't in Contentstack and your app has it when it renders, such as a view count.
Slot data. data on Slot. See Pass data into a component slot.One slot, and whatever an author drops into itAn author, on a component inside the slot, under Component DataA component holds something the components dropped inside it need, raw or worked out by that component, such as PostCard's url or a price it formatted.
Context. context on StudioComposition. See Use sections in pages outside Studio and Render a composition with your own data.The Section or Template you render with itNo one. The bindings already exist. You are filling what a template would have filled.You render a section standalone, outside a template, so nothing passes its linked schema's data for it.
Shared state. See Share state between components.Every component that uses the same keyAn author, in the Data Picker, for each variable you declareA value changes while the reader is on the page, such as a newsletter signup.

Component Data and Slot data are the same thing, at different reach​

Both arrive in the Data Picker under Component Data. What differs is how far they reach:

  • data on StudioComponent reaches every component in the template or section. Use it for something the whole page knows, such as the signed-in user.
  • data on Slot reaches only what an author drops into that one slot. Use it when a component holds something its children need. The value can be one the component was handed, or one it worked out: <Slot data={{ amount: askingPrice }}> hands amount to whatever sits in that slot, and the author binds it like any other key.

Slot data merges over what it inherits, so the nearest slot wins when both define the same key. Nesting a slot inside a slot narrows the data as you go in, rather than replacing it.

Context is a different job​

context is not another way to pass your own values. It fills the linked schema's data, the thing a template normally passes a section. You only reach for it when you render a section outside a template and nothing is doing that job for you. See Use sections in pages outside Studio.

What this is and what you get​

Component Data has two sources. Sample data is data you type in Studio. Your app's data is data your app passes when it renders. Sample data lets authors build and bind a layout before your app passes anything.

DetailSample dataYour app's data
Where it comes fromYou type it in the Data tab.Your app passes it in the data prop of StudioComponent.
Example{ "viewCount": 100 }{ viewCount: 1204 }
Saved by StudioYes, with the composition.No.
On your siteYour site uses it when your app passes no data.It takes priority over the sample data.

Your component receives a bound value the same way, whichever source the prop is bound to.

Diagram. The sample data on Post byline and your app&#39;s data both feed the Data Picker&#39;s viewCount, which ViewCount shows as 100 in Studio and 1204 on /blog/ai-101.

The example goes in five steps.

  1. In your app, a developer registers ViewCount with a count property.
  2. In Studio, an author types the sample data { "viewCount": 100 }.
  3. In Studio, the author binds Count to viewCount.
  4. In your app, the developer passes data={{ viewCount: 1204 }}.
  5. In both places, you check the result. Studio shows 100, and your site shows 1204.

Register a component with a prop to bind​

In your app. A developer does this before authors can bind anything.

Authors can bind only the props your app registers. In the example, ViewCount has one prop, count.

// src/components/ViewCount.tsx
import type { StudioAttributes } from "@contentstack/studio-react";

type Props = StudioAttributes & { count?: number };

export function ViewCount({ count, studioAttributes }: Props) {
return <span {...studioAttributes}>{count}</span>;
}
// src/register.tsx
import { registerComponents } from "@contentstack/studio-react";
import { ViewCount } from "./components/ViewCount";

registerComponents([
{
type: "ViewCount",
displayName: "ViewCount",
component: ViewCount,
wrap: false,
props: { count: { type: "number", displayName: "Count" } },
},
]);
  • count is a number prop. Studio shows it as Count in the Settings tab.
  • When an author binds Count to a value, Studio passes that value to ViewCount as count. ViewCount reads it like any React prop.
  • The registration sets wrap: false, so ViewCount spreads studioAttributes on its root element.

ViewCount appears under Registered Components in the Components tab.

For every registration option, see Register a component.

Add sample data to a composition​

In Studio. An author does this once, so there is something to bind against.

  1. Open the Data tab in the right panel. Each source you haven't set shows a card with a "Not Set" badge. The Component Data card says "Dynamic • custom data".

  2. Click the Component Data card.

    The card turns into a Component Data section with a JSON box that contains {}.

  3. Type a JSON object into the box. For the example, type { "viewCount": 100 }.

  4. Click Save to store the sample data with the composition. For a section, an Expose Props dialog opens first. Click Save in it to finish. See Build sections.

    The JSON stays in the box after a reload.

The Data tab of the Post byline section with the Component Data section open and { &quot;viewCount&quot;: 100 } in the JSON box. Nothing is selected on the canvas.

The sample data has to be a JSON object. Studio ignores a top-level array or a plain value. If the JSON is invalid, Studio shows the parser's error under the box and doesn't keep it. Click the info icon next to Component Data to read what the box is for.

The Component Data section with invalid JSON in the box and the parser&#39;s error under it.

Studio saves the sample data with the composition, so your site uses it when you deploy. Your site can use anything you type, so keep secrets out of it.

While authors edit a section, they see only its sample data, because StudioCanvas takes no data prop.

Bind a prop to your data​

In Studio. An author does this for each property that should show your data.

  1. Select a component, then open the Data Picker on one of its props, as in Bind a component. For the example, drag ViewCount from the Components tab into Post byline, select it, and open the picker on its Count property.

  2. Select the source named Component Data. Under Component Props, select ViewCount. The picker capitalizes the row for your viewCount key. Component Props lists the top-level keys of your data. Count is a number property, so it accepts number values, such as 100.

    ViewCount on the canvas shows 100.

The Data Picker on the Count property of ViewCount in Post byline, with three source icons, the last one selected. Component Props is open and the ViewCount row is listed.

The Settings tab for ViewCount with the Count property bound to viewCount, and the canvas showing ViewCount as 100.

When more than one source has data, icons along the top of the picker switch sources. Each icon shows its name on hover.

Component Data appears only when something has a value: sample data, your app's data, slot data or a state variable. The picker lists state variables you declare in the same source, under State Variable.

Pass your app's data when you render​

In your app. A developer does this on the route that renders the template. StudioComponent takes the same data prop on the client and on the server.

  1. Get specOptions for your route. On the client, useCompositionData returns it.

    const { specOptions, isLoading } = useCompositionData({ url: "/blog/ai-101" });
    if (isLoading || !specOptions) return null;

    On the server, sdk.fetchCompositionData returns specOptions, and a client component renders StudioComponent with data. See SDK API.

  2. Pass an object to the data prop of StudioComponent, next to specOptions. Each top-level key of the object becomes a key authors can bind.

    <StudioComponent specOptions={specOptions} data={{ viewCount: 1204 }} />

    Your app now passes viewCount on /blog/ai-101. The next section checks the result.

For a template or section that your app renders on its own, your app's data replaces the sample data. Studio doesn't merge the two. An empty object counts as passed data, so it hides the sample data on your site. Pass undefined when you have nothing.

A section placed in a template works differently. Studio merges the data per top-level key. It uses the template's data first, and fills any key that data lacks from the section's sample data. An empty object hides nothing there.

The template's data is the data your app passes to StudioComponent, or the template's own sample data when your app passes none. While you edit in Studio, the canvas sends your data to Studio so the picker can list it.

Check both places​

In Studio and in your app. Do this after both sides are done. The two values differ on purpose, because on your site your app's data takes priority over the sample data.

PlaceHow to open itViewCount showsWhy
StudioOpen the Post byline section on the canvas.100A section's canvas sees only its sample data.
Your siteDeploy Post byline, then open /blog/ai-101.1204Post byline is in the Blog post template, and your app's data takes priority over the sample data.

Deploying a section updates every template that uses it in that environment, such as Blog post. For the Deploy steps, see Save, preview, deploy.

If your site shows 100, your app isn't passing data on that route. See If it doesn't work.

How the Data Picker lists your data​

Use this list to see why a key or a field doesn't appear in the picker.

This is how the Data Picker lists your data.

  • Objects open as groups, and arrays list their items by position.
  • Keys that start with $ don't appear.
  • Header's Text property accepts text, number or boolean values from your data. A string property in your own component accepts text only.
  • You can bind a Repeater's Items to an array in your data. The Data Picker then lists the fields of the array's first item.
  • An empty array gives a Repeater no fields to select, so keep one item in the sample array.
  • On a template, the picker lists your app's data when the preview route passes it, and the sample data when it doesn't.

If it doesn't work​

  • The right panel has no Data tab. Turn on Enable Freeform Feature in the project's Configuration settings.
  • Component Data is missing from the picker. Nothing has a value yet. The sample data is empty or has only $ keys, and your app passes nothing.
  • The picker shows the sample data but not your app's. The route the canvas loads isn't passing data. A section's canvas never does.
  • Your site shows 100 instead of 1204. Your app passes no data on that route, so your site uses the sample data. Pass data to StudioComponent there.
  • Your site shows a prop's default value or nothing. Your app's data lacks that key, and a section placed in a template also lacks it in its sample data. If your app passes data to a template or section it renders on its own, the sample data isn't used. Add the key to your app's data.
  • A string property shows a message on the canvas that asks you to contact your development team. The property is bound to a value that is now an object or an array. See Component schema: props, types and defaults. The message reads "This content may not display correctly in this view. Please contact your development team to update the component so it can support this type of content."
  • A Repeater lists no fields. It's looping an empty array. Add one item to the sample array.

Next, bind more props in Bind a component, or look up every StudioComponent prop in SDK API.

Report a problem with this page