Schema reference
Learn how to use schemas to define the structure of your content.
Our content model system is built around the concept of schemas. Simply put, schemas are JSON configurations that outline the structure of your content for validation and editing purposes.
When you use the visual interface, a schema is automatically generated under the hood. This schema-first approach allows you to define your content visually or through a JSON file, depending on your preference.
This reference details the options for defining schemas and how they are represented in the interface.
Through the platform, you'll only interact with components, not schemas. But if you want to define your schema using JSON, this guide is for you.
Key concepts
This section covers some basic terms and concepts related to content and schemas that are essential for fully understanding the rest of this guide.
Schema
A schema is a configuration written in JSON that defines the structure of your content. It describes the attributes your content will have and their types. You can think of a schema as a template for a piece of content that you will fill in later.
Component
Components are reusable schemas for your content. When you create a component, you are essentially assigning a unique name – or identifier – to a new type of content. You can then associate this component with slots in your application or reference it in other schemas using its identifier.
We have an entire guide dedicated to components if you want to learn more.
Top-level schemas
Top-level schemas are those that define the component type. That is, to define a regular or union component, you must use a structure or union schema, respectively.
Currently, you can only create components for structures and unions. Other types, like text, number, boolean, and list, are not yet supported as top-level schemas.
Private attributes
Private attributes are those that are not exposed to the application. They are exclusively used for internal purposes, such as interpolating values in other attributes.
Schema types
The most important aspect of a schema is its type, as it determines the type of data it describes. Each type provides different options for customizing content validation and input.
You may notice that the interface uses different types than those described here. While the interface presents more user-friendly types such as Enumeration, Color, and URL, they are still represented in the schema as a Text with some additional validation.
There are currently seven types of schemas:
- Number: Numeric values, such as prices, quantities, and percentages.
- Boolean: True or false values, such as on/off or yes/no switches.
- Text: Textual values, such as titles, descriptions, and paragraphs.
- List: Collections of items such as lists of tags, images, or products.
- Structure: A group of attributes, such as a button's label and link.
- Reference: A reference to another component.
- Union: A component with multiple variants.
Each type has its own configuration options, which are detailed in the following sections.
Number
Number schemas describe numeric values such as prices, quantities, and percentages.

The input for a number schema is a text field that only accepts numbers, either integers or decimals, depending on the schema's configuration.
Properties
The following properties are available for number schemas:
- typestring
The type of the schema. Always number for number schemas.
- integer(optional)boolean
Whether to allow integral numbers only.
Default:false- minimum(optional)number
The minimum allowed value (inclusive).
Default:no minimum- maximum(optional)number
The maximum allowed value (inclusive).
Default:no maximum
Examples
Below are some examples of number schemas:
{"type": "number"}
Boolean
Boolean schemas describe true or false values such as on/off or yes/no switches.

The input for a boolean schema is a toggle button that has two labels, one for true and another for false values.
Properties
The following properties are available for boolean schemas:
- typestring
The type of the schema. Always boolean for boolean schemas.
- label(optional)Labels
A map of labels for the boolean values.
Default:"True" and "False"- default(optional)boolean
The value to be preselected on the user interface.
Default:false
Examples
Below are some examples of boolean schemas:
{"type": "boolean"}
Text
Text schemas describe textual values such as titles, colors, and URLs.

The input for a text schema can take the form of a text field, a select box, or even a file uploader, depending on the schema's configuration.
Properties
Text schemas offer several properties that allow you to customize input validation and presentation, but not all of them can be used together.
The properties format and choices cannot be used together with any other properties except for type.
The following list describes the properties of text schemas:
- typestring
The type of the schema. Always text for text schemas.
- minimumLength(optional)number
The minimum length of the text.
- maximumLength(optional)number
The maximum length of the text.
The maximum length is limited to 300 characters for single-line text and 1000 characters for multi-line text and URLs.
Default:maximum allowed- format(optional)string
The format the text must follow as listed below:
Format Description multiline A multi-line text, displayed as a text area. color A hexadecimal color code, such as #ff0000 or #f00. url A URL as defined by the URL specification. - pattern(optional)string
A regular expression the text must match, without delimiters and up to 100 characters. For example, ^[a-z0-9]+$ to only allow lowercase letters and numbers.
- choices(optional)object<string,Choice>
A map of possible values for the text, limited to 20 choices.
The keys are the values, and the values are the choice definitions as described below.
- label(optional)string
The label for the choice, up to 60 characters. For example, "Green" for the value "green".
Default:the choice value- description(optional)string
The description of the choice, up to 160 characters. For example, "Croct's brand color" for the value "green".
- default(optional)boolean
Whether the choice should be preselected on the user interface.
There can only be one default choice, otherwise the schema is considered invalid.
Default:false- position(optional)integer
The order in which the choice should appear in the list, relative to other choices.
The choices are ordered as follows:
- Choices with lower positions appear before those with higher positions.
- Choices with the same position have no guaranteed order between them.
- Choices with no position appear after those with a position.
Examples
Below are some examples of text schemas:
{"type": "text"}
List
List schemas describe collections of items such as lists of tags, images, or products.

The input for a list schema is a list of fields that allows adding, removing, and reordering items.
Properties
The following properties are available for list schemas:
- typestring
The type of the schema. Always list for list schemas.
- itemsSchema
The schema of the items in the list.
- itemLabel(optional)string
A label to prefix each item in the list, up to 60 characters. For example, "Tag" for "Tag 1", "Tag 2", and so on.
- minimumLength(optional)number
The minimum number of items (inclusive).
Default:no minimum- maximumLength(optional)number
The maximum number of items (inclusive).
Default:no maximum
Examples
Below are some examples of list schemas:
{"type": "list","items": {"type": "text"}}
Structure
Structure schemas describe groups of attributes, typically used to define whole components.

In the user interface, a structure schema appears as a form or a group of fields depending on whether it is at the root level or nested within another schema.
Properties
The following properties are available for structure schemas.
- typestring
The type of the schema. Always structure for structure schemas.
- title(optional)string
The title of the structure, up to 60 characters.
This value is used as the label in lists and union selectors.
- description(optional)string
The description of the structure, up to 160 characters.
This value is used as help text for the group of fields in the interface.
- attributes(optional)object<string,Attribute>
The mapping of attribute names to their definitions.
- typeSchema
The type of the attribute. Can be any of the schema types.
- label(optional)string
The label of the attribute, up to 60 characters.
This value is used as the label of the field in the interface.
- description(optional)string
The description of the attribute, up to 160 characters.
This value is used as help text for the field in the interface.
- optional(optional)boolean
Whether the attribute is optional.
Default:false- private(optional)boolean
Whether the attribute must be hidden from the application.
Default:false- position(optional)integer
The order in which the attribute should be displayed, relative to other attributes.
The attributes are ordered as follows:
- Attributes with lower positions appear before those with higher positions.
- Attributes with the same position have no guaranteed order between them.
- Attributes with no position appear after those with a position.
Default:no specific order
Examples
Below are some examples of structure schemas:
{"type": "structure","title": "CTA Button","description": "A call-to-action button that links to a page.","attributes": {"label": {"label": "Label","description": "The text displayed on the button.","position": 0,"type": {"type": "text"}},"link": {"label": "Link","description": "The URL of the page to link to.","position": 1,"type": {"type": "text"}}}}
Reference
Reference schemas allow you to reuse components that appear in multiple places.

The input for a reference schema is the same as the input for the referenced component.
Properties
The following properties are available for reference schemas:
- typestring
The type of the schema. Always reference for reference schemas.
- idstring
The ID of the referenced component.
Examples
Below are some examples of reference schemas:
{"type": "reference","id": "button"}
Union
Union schemas allow you to define a schema that can be one of several types.

The input for a union schema is a dropdown that allows selecting one of the possible types.
Properties
The union schema is straightforward and only have one specific property that maps component IDs to their reference schemas.
The keys of the types object must match the IDs of the components referenced. Otherwise, the schema is considered invalid.
The following list describes the properties of union schemas:
- typestring
The type of the schema. Always union for union schemas.
- typesobject<string,Reference>
The mapping of component IDs to their reference schemas, limited to 10 components.
Examples
Below are some examples of how to use union schemas.
Keep in mind that the text-hero and image-hero components are just examples for demonstration purposes, and you can use any components available to you.
{"type": "union","types": {"text-hero": {"type": "reference","id": "text-hero"},"image-hero": {"type": "reference","id": "image-hero"}}}
Built-in components
In addition to the types described above, there are some predefined components with specific configurations and interfaces that you can use right out of the box.
The following sections describe these components and how to use them.
File
The @croct/file component represents a URL that links to an uploaded file, such as an image, music, or video file. This component is essentially a text schema with some additional validation for file uploads.
In the user interface, it appears as a file uploader:

To use this component, define a reference schema as follows:
{"type": "reference","id": "@croct/file","properties": {}}
To define the validation rules for file uploads, use the properties described below.
Properties
These are the properties available for file schemas:
- allowedTypes(optional)array<string>
The allowed file types. For example, to allow only PNG and JPEG images, set this property to ["image/png", "image/jpeg"].
Default:any type from the table below- minimumSize(optional)number
The minimum file size in bytes, inclusive. For example, to allow only files larger than 10KB, set this property to 10240.
Default:no minimum- maximumSize(optional)number
The maximum file size in bytes, inclusive. For example, to allow only files smaller than 1MB, set this property to 1048576.
The maximum file size is limited to 5MB, or 5242880 bytes.
Default:5242880 bytes (5MB)
Below is a table with the file types that are currently supported. You should use the values in the File type column to indicate the specific file types you want to allow.
File type | Extensions |
---|---|
image/png | png |
image/jpeg | jpe, jpeg, jpg |
image/jp2 | jp2, jpg2 |
image/webp | webp |
image/gif | gif |
image/svg+xml | svg, svgz |
image/avif | avif |
video/mp4 | mp4, mp4v, mpg4 |
video/quicktime | mov, qt |
video/x-webm | webm |
audio/mpeg | m2a, m3a, mp2, mp2a, mp3, mpga |
audio/mp4 | mp4, mp4a |
audio/wav | wav |
audio/x-wav | wav |
audio/x-ms-wma | wma |
audio/ogg | oga, ogg, opus, spx |
audio/aac | adts, aac |
application/json | json |
text/plain | txt |
Examples
{"type": "reference","id": "@croct/file","properties": {}}
Complexity
When designing a component, it is important to keep in mind that the more complex a component is, the more difficult it is to create and update content.
The complexity score tells how complex a component is based on its structure and attributes. The higher the score, the more complex the component.
To calculate the score, start with 0 and then add up the complexity of the component's attributes as follows:
- Structures: Count 1 for the structure itself, and add the complexity of its attributes.
- Lists: Count 1 for the list itself, and add the complexity of its item types.
- Primitives: Count 1 for each primitive type (text, boolean, and number).
- Unions: Add the complexity of the most complex component in the union.
- References: Add the complexity of the referenced component.
Now let's apply this to an example. Suppose we have a product listing component that contains a list of products. Each product has a title, an image, and a price. The complexity of the component would be calculated as follows:
- Count 1 for the list
- Count 1 for the product structure
- Count 1 for each of the product attributes (title, image, and price).
That gives us a complexity score of 5.
Limits
We enforce some limits on content schemas to ensure that components remain performant and manageable as your content model evolves.
These are the limits that apply to components:
- Up to 30 attributes per structure
- Up to 5 component references
- Nesting up to 5 levels deep
- Maximum of 10 components in a union
- Maximum complexity score of 50.
For tips on designing components that are both flexible and maintainable, check out the Component Design guide.
Further reading
For more on content and related topics, check out the following resources: