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.

Croct's mascot neutral
Do I need to read this?

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.

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.

Number input

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.

Boolean input

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.

truestring

The label for representing true, up to 60 characters.

falsestring

The label for representing false, up to 60 characters.

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.

Text input

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 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.

Default:maximum allowed
format(optional)string

The format the text must follow as listed below:

FormatDescription
multilineA multi-line text, displayed as a text area.
colorA hexadecimal color code, such as #ff0000 or #f00.
urlA 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".

You can use this description to provide additional information about the option. It supports basic Markdown formatting, including:

  • Bold: To make text bold, enclose it in double asterisks. For example, **Bold** displays Bold.
  • Italic: To italicize text, enclose it in single asterisks. For example, *Italic* appears as Italic.
  • Code: To display text in a monospaced font, enclose it in backticks. For example, code displays code.
  • Link: To create links, use square brackets followed by parentheses. For example, [Croct](https://croct.com) becomes Croct.
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.

List form

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.

Item label
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.

Structure form

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.

You can use this description to provide additional details about nested attributes. It supports basic Markdown formatting, including:

  • Bold: To make text bold, enclose it in double asterisks. For example, **Bold** displays Bold.
  • Italic: To italicize text, enclose it in single asterisks. For example, *Italic* appears as Italic.
  • Code: To display text in a monospaced font, enclose it in backticks. For example, code displays code.
  • Link: To create links, use square brackets followed by parentheses. For example, [Croct](https://croct.com) becomes Croct.
attributes(optional)object<string,Attribute>

The mapping of attribute names to their definitions.

Attribute anatomy
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.

You can use this description to provide additional details about the attribute. It supports basic Markdown formatting, including:

  • Bold: To make text bold, enclose it in double asterisks. For example, **Bold** displays Bold.
  • Italic: To italicize text, enclose it in single asterisks. For example, *Italic* appears as Italic.
  • Code: To display text in a monospaced font, enclose it in backticks. For example, code displays code.
  • Link: To create links, use square brackets followed by parentheses. For example, [Croct](https://croct.com) becomes Croct.
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.

Reference form

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.

Union form

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 following list describes the properties of union schemas:

titlestring

The title of the union, up to 60 characters.

This value is used as the label in lists and component selectors.

descriptionstring

The description of the union, up to 160 characters.

You can use this description to provide additional details about the types available. It supports basic Markdown formatting, including:

  • Bold: To make text bold, enclose it in double asterisks. For example, **Bold** displays Bold.
  • Italic: To italicize text, enclose it in single asterisks. For example, *Italic* appears as Italic.
  • Code: To display text in a monospaced font, enclose it in backticks. For example, code displays code.
  • Link: To create links, use square brackets followed by parentheses. For example, [Croct](https://croct.com) becomes Croct.
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:

File input

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.

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 typeExtensions
image/pngpng
image/jpegjpe, jpeg, jpg
image/jp2jp2, jpg2
image/webpwebp
image/gifgif
image/svg+xmlsvg, svgz
image/avifavif
video/mp4mp4, mp4v, mpg4
video/quicktimemov, qt
video/x-webmwebm
audio/mpegm2a, m3a, mp2, mp2a, mp3, mpga
audio/mp4mp4, mp4a
audio/wavwav
audio/x-wavwav
audio/x-ms-wmawma
audio/oggoga, ogg, opus, spx
audio/aacadts, aac
application/jsonjson
text/plaintxt

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: