A schema is a JSON file that defines which data is collected for the schema from the studio and the API hub.
A schema can be for:
- Frontend components
- Dynamic pages
- Page folders
- Project settings
- Data sources
This article will go through the general schema structure for all our schemas, schema field types, and how to access the data.
General schema structure
The basic structure of a schema is as follows:
You can store the schema.json file wherever you like, because it's only required in the studio and not by the code.
<schema>Type is the most important piece as it connects the schema to the React component in your project and they must be identical to the mapping defined there.
name is also important because this is what the user sees in the studio.
category can be whatever you choose to organize your schemas in the studio.
icon can be used to define a speaking icon from Material icons.
schema section is an array of configuration sections.
These are displayed in different parts of the studio. For example, for Frontend components, these are displayed in the component editor panel.
You can move around fields between these sections as you like because the resulting
data property will be flat (without the sections). They're only for visualization purposes in the studio. That also means that every field identifier (see below) must be unique across the entire schema. The only exceptions are fields that are part of a
group (also see below).
schema section has a
name (the section headline in the component editor panel) and a number of
Each object in
fields consists of a similar structure which can slightly differ depending on the
type of the field, for example:
Each field has a
label which is displayed to the user as the prompt to insert some information.
field determines how you can access the field in the data prop. Remember that field identifiers must be unique across a schema.
type determines what kind of information should be input by the user in the studio. We'll go through these in the next section of this article.
The remaining properties of a field are optional and help you to configure the behavior of the field in the studio:
translatable: Determines if the field value should be available in different languages (see the internationalization article for more information. The default of this setting depends on the field type (see below). Learn more about using multiple languages for a field on the locales and translations article.
false): If the setting is mandatory in the studio. You'll still need to check if the value is set in your Frontend component code because it might not be loaded yet (asynchronous) or the user in the studio ignored the warning about a mandatory setting (for example, to store a draft).
null): Define a custom default value you want to receive when the config is left empty in the studio.
null): Array of key-value pairs defining values for
enumfield type. Providing this field is mandatory when the field type is set to
Schema field types
For the field
type, we have certain options you can use:
Simple field types
There're a number of simple field types that allow different configuration inputs. The more complex types (
group) are explained further below.
|Field type||Default||Description||Example of how it looks in the studio|
|1-line input field.|
|Multi-line input field.|
|Allows the user to write simply formatted text using Markdown (see our using the markdown editor article for more information). You'll receive the raw Markdown string and can render it in your component using |
|Not translatable||Lets the user input a numeric value.|
|Not translatable||Presents a select box to pick a single value from it. The selectable values are set through the additional property |
|Not translatable||A simple switch that returns |
|Not translatable||Lets the user select an image from the media library and configure some additional settings such as an |
|Not translatable||Lets the user select a page folder from the page folder tree in the site builder and returns the corresponding page folder ID. You can use the |
|A reference can either be a page folder (like from the node type) or an external link URL. If you want to give the user the choice, use this type. You can use the |
|Not translatable||The user can select a page folder in the site builder and you'll receive the entire sub-tree of page folders that starts there. This is especially handy if you want to render a navigation.|
|Not translatable||The user will see an input box and when they click, they'll see a calendar and a clock to select a date and time. NOTE: The time and date selected is based on the users local time.|
|Not translatable||This field type is meant for copy and paste of complex information (for example, exports from other systems). You can ask users to paste some JSON and will receive it automatically parsed to an object.|
Code examples for each type:
Data source fields
The field type
dataSource is special in the sense that you won't receive the user-entered configuration but the result from a data source query.
For example, if you have
dataSourceType: product-list, the studio user will be able to filter products from the commerce backend by various criteria. In your Frontend component, you'll simply receive the products that are returned by this query.
Every field of type
dataSource needs a
It'll display as in the studio as below:
As you're creating a schema for a data source, the possible values for
dataSourceType need to match what you've inputted in your data source schema.
Group inputs for Frontend components
In some cases, a single input isn't enough. Then you typically don't want to have multiple fields like
image3 but use a field of type
group to let the user in the studio create a flexible number of group elements as values for the field.
The elements of a
group can contain any number of fields again. The basic configuration of a
group looks like this:
Always use a label as the first option along with
"itemLabelField": "name"so that this is displayed in the component settings panel.
This schema creates a
category fields. The user in the studio can add a number of
name items (at least 1, up to 5,
max are optional) in the
group and as the value, you receive an array of these elements in your Frontend component.
Then if you click the edit icon on a country or + Add countries, you'll get pop-up settings:
You can provide additional information to your users in the studio by using the field type
image. In contrast to normal fields, this doesn't expect the
field properties, only a
type plus their specific value properties. For example:
You can also use
helpText which displays at the top of the section and appears on hover:
When you first create a Frontend component schema only make configurable what really needs to be configured in the studio. In some cases, it means that nothing will be configurable. For example, the checkout Frontend component is only placed on the page and the code takes care of the rest. It's only when your team needs something to be configurable should you add it into your schema.
If you ever add any new configurations to an existing Frontend component, they must be optional and set to a default that will result in the old behavior (for example,
false in the example above).
Copy the schema of your latest and most simple Frontend component or a similar Frontend component to what you want to create as a starting point for your new schema. Test it to make sure it works and then tweak it to how you want it. That way you don't have to rewrite a lot of code, you keep the same format and conventions, and you know how it'll behave.
Keep as much business logic outside of the Frontend component itself and put that into the patterns or explicit logic components. Use the Frontend component as a data layer to feed the components. It might even be a good idea to translate the data structure coming from API hub into your own semantic data structure to increase the re-use of your components.
When deciding how to slice up a Frontend component, it's sometimes best to make one big block in the first instance and then refactor only if you need to make smaller parts configurable. Think about how it will be used and how it makes sense from a user point of view. If it makes sense from the get-go to make 2 (or more) smaller Frontend component, then make it like that. But if you're not sure how to split it up, make 1 big one. It'll save you setup time, and you won't have to think about so many possibilities to account for in your code. You can always cut it down in the future. You can even use our grid system within a Frontend component, which will then make it easier when refactoring and will make it all look the same even if you're using 1 big Frontend component versus 4 small Frontend component.
In general, take each Frontend component on a case-by-case basis. In some cases, some of these best practices won't work for the individual Frontend component you're creating as it's unique and how you handle it is unique.
If you want to, you could limit the number of products that will be displayed to your customers in a product slider, or add a title to it, or even a description. You can add all these things and more into the schema of your component and make them configurable by the users of the studio.