Documentation
Feedback
Guides
Storefront Development

Storefront Development
Store FrameworkWorking with Site Editor
Site Editor schema examples

Explore practical schema examples for configuring custom components in Site Editor.

When configuring a custom component, you need to define a schema within it to make it editable by user administrators directly in Site Editor. Learn how to configure the schema definitions in the Making a custom component available in Site Editor guide.

To create your schemas, use the JSON Schema format, a declarative language that provides a standardized way to describe and validate JSON data.

You can use the following data types to configure your schemas:

In this guide, you will learn how to use each data type effectively.

String

Alongside, you can see the HeaderComponentProps interface, which specifies the types of the title and subtitle props. This interface is used to type-check the props passed to the HeaderComponent.

The HeaderComponent is a functional component that accepts title and subtitle as props, which are destructured from the props object defined by the interface.

Below are additional examples of content schemas using String for image and date fields.

HeaderComponent.tsx

_37
import React from 'react';
_37
_37
interface HeaderComponentProps {
_37
title: string;
_37
subtitle: string;
_37
}
_37
_37
const HeaderComponent = ({ title, subtitle }: HeaderComponentProps) => {
_37
return (
_37
<>
_37
<p>{title}</p>
_37
<p>{subtitle}</p>
_37
</>
_37
);
_37
};
_37
_37
HeaderComponent.defaultProps = {
_37
title: "VTEX",
_37
subtitle: "The Composable and Complete Commerce Platform.",
_37
};
_37
_37
HeaderComponent.schema = {
_37
title: 'Custom Component',
_37
type: 'object',
_37
properties: {
_37
title: {
_37
type: 'string',
_37
title: 'Título',
_37
},
_37
subtitle: {
_37
type: 'string',
_37
title: 'Subtítulo',
_37
},
_37
},
_37
};
_37
_37
export default CustomComponent;

Images

Consider a component that displays different images based on device type (desktop or mobile) (e.g., ImageComponent.tsx).

To enable users to select an image from their computer or paste an image URL link, provide options for both methods in your component’s schema object.

HeaderComponent.tsx
ImageComponent.tsx

_38
import React from 'react';
_38
_38
interface ImageComponentProps {
_38
imageDesktop: string;
_38
imageMobile: string;
_38
}
_38
_38
function ImageComponent({ imageDesktop, imageMobile }: ImageComponentProps) {
_38
return(
_38
<div>
_38
<img src={imageDesktop} />
_38
<img src={imageMobile} />
_38
</div>
_38
);
_38
}
_38
_38
ImageComponent.schema = {
_38
title: 'Custom Component',
_38
type: 'object',
_38
properties: {
_38
imageDesktop: {
_38
type: 'string',
_38
title: 'Image Desktop',
_38
default: '',
_38
description: 'Paste the URL'
_38
},
_38
imageMobile: {
_38
title: 'Image Mobile',
_38
default: '',
_38
type: 'string',
_38
widget: {//here you can choose a file in your computer
_38
"ui:widget": "image-uploader"
_38
}
_38
}
_38
}
_38
};
_38
_38
export default ImageComponent;

In Site Editor, this custom component will look like this:

{"base64":"  ","img":{"width":284,"height":462,"type":"png","mime":"image/png","wUnits":"px","hUnits":"px","length":18098,"url":"https://cdn.jsdelivr.net/gh/vtexdocs/dev-portal-content@main/docs/guides/vtex-io/Storefront-Guides/images/string-image-custom-component.png"}}

Dates

Consider a component that allows users to input a start and end date (e.g., DateComponentProps.tsx).

In the schema, the initialDate and finalDate props define the configuration for date input fields.

HeaderComponent.tsx
ImageComponent.tsx
DateComponent.tsx

_39
import React from 'react';
_39
_39
interface DateComponentProps {
_39
initialDate: string;
_39
finalDate: string;
_39
}
_39
_39
function DateComponent({ initialDate, finalDate }: DateComponentProps) {
_39
return(
_39
<div>
_39
<p>{initialDate}</p>
_39
<p>{finalDate}</p>
_39
</div>
_39
);
_39
}
_39
_39
DateComponent.schema = {
_39
title: 'Custom Component',
_39
type: 'object',
_39
properties: {
_39
initialDate: {
_39
type: 'string',
_39
title: 'Initial Date',
_39
default: '',
_39
description: '{year}/{month}/{day}'
_39
},
_39
finalDate: {
_39
title: 'Final Date', //2022-02-23T02:20:42.074Z
_39
default: new Date().toISOString(), //Set current date in select input
_39
type: 'string', //to user select a date.
_39
format: 'date-time',
_39
widget: {
_39
"ui:widget": "datetime"
_39
}
_39
}
_39
}
_39
};
_39
_39
export default DateComponent;

The initialDate prop has an empty string as its default value and a description indicating the expected date format '{year}/{month}/{day}'. The finalDate prop has the default value set to the current date and time in ISO 8601 format. It includes a custom UI widget for a date-time picker, streamlining the selection of both date and time.

In Site Editor, this component will look like this:

{"base64":"  ","img":{"width":290,"height":396,"type":"png","mime":"image/png","wUnits":"px","hUnits":"px","length":22394,"url":"https://cdn.jsdelivr.net/gh/vtexdocs/dev-portal-content@main/docs/guides/vtex-io/Storefront-Guides/images/string-date-custom-component.png"}}

Boolean

Consider a component that allows users to toggle its active or inactive state. To allow users to activate or deactivate the component, define the schema as follows.

HeaderComponent.tsx
ImageComponent.tsx
DateComponent.tsx
BooleanComponent.tsx

_33
import React from 'react';
_33
_33
interface BooleanComponentProps {
_33
active: boolean;
_33
}
_33
_33
function BooleanComponent ({ active }: BooleanComponentProps) {
_33
if(!active) return;
_33
_33
return(
_33
<div>
_33
<h2>Now the component is active!</h2>
_33
</div>
_33
);
_33
}
_33
_33
BooleanComponent.defaultProps = {
_33
active: true,
_33
};
_33
_33
BooleanComponent.schema = {
_33
title: 'Custom Component',
_33
type: 'object',
_33
properties: {
_33
active: {
_33
type: 'boolean',
_33
title: 'Active Component',
_33
default: true,
_33
}
_33
}
_33
};
_33
_33
export default BooleanComponent;

The active prop is a boolean, meaning it can be either true or false. The default value set as true ensures that the component starts in an active state unless specified otherwise.

In Site Editor, this custom component will look like this:

{"base64":"  ","img":{"width":334,"height":297,"type":"png","mime":"image/png","wUnits":"px","hUnits":"px","length":43634,"url":"https://cdn.jsdelivr.net/gh/vtexdocs/dev-portal-content@main/docs/guides/vtex-io/Storefront-Guides/images/boolean-custom-component.png"}}

Object

Consider a component that renders an image, taking an image prop, which includes the URL, alt text, and title.

The schema below defines the structure of the component, specifying that it expects an image prop, which is an object containing url, alt, and title props.

HeaderComponent.tsx
ImageComponent.tsx
DateComponent.tsx
BooleanComponent.tsx
ObjectComponent.tsx

_51
import React from 'react';
_51
_51
interface ImageProps {
_51
url: string;
_51
alt: string;
_51
title: string;
_51
}
_51
_51
interface ObjectComponentProps {
_51
image: ImageProps;
_51
}
_51
_51
function ObjectComponent({ image }: ObjectComponentProps) {
_51
return(
_51
<div>
_51
<img
_51
src={image.url}
_51
alt={image.alt}
_51
title={image.title}
_51
/>
_51
</div>
_51
);
_51
}
_51
_51
ObjectComponent.schema = {
_51
title: 'Custom Component',
_51
type: 'object',
_51
properties: {
_51
image: {
_51
title: 'Image Prop',
_51
type: 'object',
_51
properties: {
_51
src: {
_51
type: 'string',
_51
title: 'Image URL',
_51
description: 'URL image'
_51
},
_51
alt: {
_51
type: 'string',
_51
title: 'Image Text Alternative',
_51
},
_51
title: {
_51
type: 'string',
_51
title: 'Attribute title',
_51
},
_51
}
_51
}
_51
}
_51
};
_51
_51
export default ObjectComponent;

In Site Editor, this component will look like this:

{"base64":"  ","img":{"width":390,"height":570,"type":"png","mime":"image/png","wUnits":"px","hUnits":"px","length":34623,"url":"https://cdn.jsdelivr.net/gh/vtexdocs/dev-portal-content@main/docs/guides/vtex-io/Storefront-Guides/images/object-custom-component.png"}}

Array

Consider a component where the displayed images adapt to the screen size.

The component checks if the viewport width is less than 768 pixels to determine if it is a mobile view and selects the appropriate image source. It then renders the images inside a div, with each img element receiving the correct source and alt text based on the viewport size, ensuring each image has a unique key.

In the schema, the images prop is specified as an array of objects, ensuring it will hold multiple items. Each item within the images array is defined as an object with three specific props, src, alt, and mobileSrc.

HeaderComponent.tsx
ImageComponent.tsx
DateComponent.tsx
BooleanComponent.tsx
ObjectComponent.tsx
ArrayComponent.tsx

_70
import React from 'react'
_70
_70
interface ImageProps {
_70
src: string;
_70
alt: string;
_70
mobileSrc: string;
_70
}
_70
_70
interface ArrayComponentProps
_70
images: ImageProps[];
_70
}
_70
_70
function ArrayComponent({ images }: ArrayComponentProps) {
_70
const isMobile = window.innerWidth < 768;
_70
_70
return(
_70
<div>
_70
{
_70
images.map((image, index) => (
_70
<img
_70
alt={image.alt}
_70
key={index}
_70
src={isMobile ? image.mobileSrc : image.src}
_70
/>
_70
))
_70
}
_70
</div>
_70
);
_70
}
_70
_70
ArrayComponent.schema = {
_70
title: 'Custom Component',
_70
type: 'object',
_70
properties: {
_70
images: {
_70
type: 'array',
_70
title: 'Images',
_70
default: [
_70
{
_70
src: '',
_70
alt: 'Text alternative',
_70
mobileSrc: ''
_70
}
_70
],
_70
items: {//item configuration
_70
type: 'object',
_70
title: 'Image',
_70
properties: {
_70
src: {
_70
type: 'string',
_70
title: 'Image SRC',
_70
description: 'Image URL [desktop]'
_70
},
_70
alt: {
_70
type: 'string',
_70
title: 'Image Text Alternative',
_70
description: 'Image URL'
_70
},
_70
mobileSrc: {
_70
type: 'string',
_70
title: 'Image SRC [mobile]',
_70
description: 'Image URL'
_70
},
_70
}
_70
}
_70
}
_70
}
_70
};
_70
_70
export default ArrayComponent;

In Site Editor, this component will look like this:

{"base64":"  ","img":{"width":555,"height":481,"type":"png","mime":"image/png","wUnits":"px","hUnits":"px","length":61155,"url":"https://cdn.jsdelivr.net/gh/vtexdocs/dev-portal-content@main/docs/guides/vtex-io/Storefront-Guides/images/array-custom-component.png"}}

Making the item name editable

If you want to allow users to change the name of each item in the images array within Site Editor, add the __editorItemTitle prop to the item configuration.

HeaderComponent.tsx
ImageComponent.tsx
DateComponent.tsx
BooleanComponent.tsx
ObjectComponent.tsx
ArrayComponent.tsx

_75
import React from 'react'
_75
_75
interface ImageProps {
_75
src: string;
_75
alt: string;
_75
mobileSrc: string;
_75
}
_75
_75
interface ArrayComponentProps
_75
images: ImageProps[];
_75
}
_75
_75
function ArrayComponent({ images }: ArrayComponentProps) {
_75
const isMobile = window.innerWidth < 768;
_75
_75
return(
_75
<div>
_75
{
_75
images.map((image, index) => (
_75
<img
_75
alt={image.alt}
_75
key={index}
_75
src={isMobile ? image.mobileSrc : image.src}
_75
/>
_75
))
_75
}
_75
</div>
_75
);
_75
}
_75
_75
ArrayComponent.schema = {
_75
title: 'Custom Component',
_75
type: 'object',
_75
properties: {
_75
images: {
_75
type: 'array',
_75
title: 'Images',
_75
default: [
_75
{
_75
src: '',
_75
alt: 'Text alternative',
_75
mobileSrc: ''
_75
}
_75
],
_75
items: { //item configuration
_75
type: 'object',
_75
title: 'Image',
_75
properties: {
_75
__editorItemTitle: { // now change name is available
_75
default: 'Image Item',
_75
title: 'Change item name',
_75
type: 'string'
_75
},
_75
src: {
_75
type: 'string',
_75
title: 'Image SRC',
_75
description: 'Image URL [desktop]'
_75
},
_75
alt: {
_75
type: 'string',
_75
title: 'Image Text Alternative',
_75
description: 'Image URL'
_75
},
_75
mobileSrc: {
_75
type: 'string',
_75
title: 'Image SRC [mobile]',
_75
description: 'Image URL'
_75
},
_75
}
_75
}
_75
}
_75
}
_75
};
_75
_75
export default ArrayComponent;

In Site Editor, this component will look like this:

{"base64":"  ","img":{"width":742,"height":547,"type":"png","mime":"image/png","wUnits":"px","hUnits":"px","length":53781,"url":"https://cdn.jsdelivr.net/gh/vtexdocs/dev-portal-content@main/docs/guides/vtex-io/Storefront-Guides/images/array-item-custom-component.png"}}

enum and enumNames props

Some props are used to define a set of allowed values for a particular prop, such as enum and enumNames.

When using enum, the prop's value must be one of the values in the array.

The enumNames prop is used in conjunction with enum to provide a set of human-readable names for the values specified in the enum array. This is particularly useful in UI components, such as dropdowns and radio buttons, where you want to display a user-friendly name instead of the actual value.

enum example

Imagine you have a schema with colors as a prop, and the possible values are red, blue, or black.

HeaderComponent.tsx
ImageComponent.tsx
DateComponent.tsx
BooleanComponent.tsx
ObjectComponent.tsx
ArrayComponent.tsx
EnumComponent.tsx

_32
import React from 'react';
_32
_32
interface EnumComponentProps {
_32
colors: 'red' | 'blue' | 'black';
_32
}
_32
_32
const EnumComponent = ({ colors }: EnumComponentProps) => {
_32
return (
_32
<div>
_32
<p>{`Selected color: ${colors}`}</p>
_32
</div>
_32
);
_32
};
_32
_32
EnumComponent.defaultProps = {
_32
colors: 'red',
_32
};
_32
_32
EnumComponent.schema = {
_32
title: 'Custom Component',
_32
type: 'object',
_32
properties: {
_32
colors: {
_32
type: 'string',
_32
title: 'Color',
_32
default: 'red',
_32
enum: ['red', 'blue', 'black'] // allowed values for the `colors` prop
_32
}
_32
}
_32
};
_32
_32
export default EnumComponent

In Site Editor, you will see the component like this:

{"base64":"  ","img":{"width":730,"height":493,"type":"png","mime":"image/png","wUnits":"px","hUnits":"px","length":54254,"url":"https://cdn.jsdelivr.net/gh/vtexdocs/dev-portal-content@main/docs/guides/vtex-io/Storefront-Guides/images/enum-example.png"}}

enumNames example

Imagine you have a schema with colors as a prop, and the possible values are #0ff102, #1038c9, or #000000. However, for the user, you need to show the names green, blue, or black, respectively.

HeaderComponent.tsx
ImageComponent.tsx
DateComponent.tsx
BooleanComponent.tsx
ObjectComponent.tsx
ArrayComponent.tsx
EnumComponent.tsx
EnumNamesComponent.tsx

_39
import React from 'react';
_39
_39
interface EnumNamesComponentProps {
_39
colors: '#0ff102' | '#1038c9' | '#000000';
_39
}
_39
_39
const EnumNamesComponent = ({ colors }: EnumNamesComponentProps) => {
_39
const colorNames: { [key: string]: string } = {
_39
'#0ff102': 'green',
_39
'#1038c9': 'blue',
_39
'#000000': 'black',
_39
};
_39
_39
return (
_39
<div>
_39
<p>{`Selected color: ${colorNames[colors]}`}</p>
_39
</div>
_39
);
_39
};
_39
_39
EnumNamesComponent.defaultProps = {
_39
colors: '#0ff102',
_39
};
_39
_39
EnumNamesComponent.schema = {
_39
title: 'Custom Component',
_39
type: 'object',
_39
properties: {
_39
colors: {
_39
type: 'string',
_39
title: 'Color',
_39
default: '#0ff102',
_39
enumNames: ['green', 'blue', 'black'],
_39
enum: ['#0ff102', '#1038c9', '#000000'], // allowed values for the `colors` prop
_39
},
_39
},
_39
};
_39
_39
export default EnumComponent;

In Site Editor, you will see this component like this:

{"base64":"  ","img":{"width":728,"height":440,"type":"png","mime":"image/png","wUnits":"px","hUnits":"px","length":142239,"url":"https://cdn.jsdelivr.net/gh/vtexdocs/dev-portal-content@main/docs/guides/vtex-io/Storefront-Guides/images/enum-enumname-example.png"}}

If the user selects the value green, for example, the prop returns #0ff102.

String

Alongside, you can see the HeaderComponentProps interface, which specifies the types of the title and subtitle props. This interface is used to type-check the props passed to the HeaderComponent.

The HeaderComponent is a functional component that accepts title and subtitle as props, which are destructured from the props object defined by the interface.

Below are additional examples of content schemas using String for image and date fields.

Images

Consider a component that displays different images based on device type (desktop or mobile) (e.g., ImageComponent.tsx).

To enable users to select an image from their computer or paste an image URL link, provide options for both methods in your component’s schema object.

In Site Editor, this custom component will look like this:

{"base64":"  ","img":{"width":284,"height":462,"type":"png","mime":"image/png","wUnits":"px","hUnits":"px","length":18098,"url":"https://cdn.jsdelivr.net/gh/vtexdocs/dev-portal-content@main/docs/guides/vtex-io/Storefront-Guides/images/string-image-custom-component.png"}}

Dates

Consider a component that allows users to input a start and end date (e.g., DateComponentProps.tsx).

In the schema, the initialDate and finalDate props define the configuration for date input fields.

The initialDate prop has an empty string as its default value and a description indicating the expected date format '{year}/{month}/{day}'. The finalDate prop has the default value set to the current date and time in ISO 8601 format. It includes a custom UI widget for a date-time picker, streamlining the selection of both date and time.

In Site Editor, this component will look like this:

{"base64":"  ","img":{"width":290,"height":396,"type":"png","mime":"image/png","wUnits":"px","hUnits":"px","length":22394,"url":"https://cdn.jsdelivr.net/gh/vtexdocs/dev-portal-content@main/docs/guides/vtex-io/Storefront-Guides/images/string-date-custom-component.png"}}

Boolean

Consider a component that allows users to toggle its active or inactive state. To allow users to activate or deactivate the component, define the schema as follows.

The active prop is a boolean, meaning it can be either true or false. The default value set as true ensures that the component starts in an active state unless specified otherwise.

In Site Editor, this custom component will look like this:

{"base64":"  ","img":{"width":334,"height":297,"type":"png","mime":"image/png","wUnits":"px","hUnits":"px","length":43634,"url":"https://cdn.jsdelivr.net/gh/vtexdocs/dev-portal-content@main/docs/guides/vtex-io/Storefront-Guides/images/boolean-custom-component.png"}}

Object

Consider a component that renders an image, taking an image prop, which includes the URL, alt text, and title.

The schema below defines the structure of the component, specifying that it expects an image prop, which is an object containing url, alt, and title props.

In Site Editor, this component will look like this:

{"base64":"  ","img":{"width":390,"height":570,"type":"png","mime":"image/png","wUnits":"px","hUnits":"px","length":34623,"url":"https://cdn.jsdelivr.net/gh/vtexdocs/dev-portal-content@main/docs/guides/vtex-io/Storefront-Guides/images/object-custom-component.png"}}

Array

Consider a component where the displayed images adapt to the screen size.

The component checks if the viewport width is less than 768 pixels to determine if it is a mobile view and selects the appropriate image source. It then renders the images inside a div, with each img element receiving the correct source and alt text based on the viewport size, ensuring each image has a unique key.

In the schema, the images prop is specified as an array of objects, ensuring it will hold multiple items. Each item within the images array is defined as an object with three specific props, src, alt, and mobileSrc.

In Site Editor, this component will look like this:

{"base64":"  ","img":{"width":555,"height":481,"type":"png","mime":"image/png","wUnits":"px","hUnits":"px","length":61155,"url":"https://cdn.jsdelivr.net/gh/vtexdocs/dev-portal-content@main/docs/guides/vtex-io/Storefront-Guides/images/array-custom-component.png"}}

Making the item name editable

If you want to allow users to change the name of each item in the images array within Site Editor, add the __editorItemTitle prop to the item configuration.

In Site Editor, this component will look like this:

{"base64":"  ","img":{"width":742,"height":547,"type":"png","mime":"image/png","wUnits":"px","hUnits":"px","length":53781,"url":"https://cdn.jsdelivr.net/gh/vtexdocs/dev-portal-content@main/docs/guides/vtex-io/Storefront-Guides/images/array-item-custom-component.png"}}

enum and enumNames props

Some props are used to define a set of allowed values for a particular prop, such as enum and enumNames.

When using enum, the prop's value must be one of the values in the array.

The enumNames prop is used in conjunction with enum to provide a set of human-readable names for the values specified in the enum array. This is particularly useful in UI components, such as dropdowns and radio buttons, where you want to display a user-friendly name instead of the actual value.

enum example

Imagine you have a schema with colors as a prop, and the possible values are red, blue, or black.

In Site Editor, you will see the component like this:

{"base64":"  ","img":{"width":730,"height":493,"type":"png","mime":"image/png","wUnits":"px","hUnits":"px","length":54254,"url":"https://cdn.jsdelivr.net/gh/vtexdocs/dev-portal-content@main/docs/guides/vtex-io/Storefront-Guides/images/enum-example.png"}}

enumNames example

Imagine you have a schema with colors as a prop, and the possible values are #0ff102, #1038c9, or #000000. However, for the user, you need to show the names green, blue, or black, respectively.

In Site Editor, you will see this component like this:

{"base64":"  ","img":{"width":728,"height":440,"type":"png","mime":"image/png","wUnits":"px","hUnits":"px","length":142239,"url":"https://cdn.jsdelivr.net/gh/vtexdocs/dev-portal-content@main/docs/guides/vtex-io/Storefront-Guides/images/enum-enumname-example.png"}}

If the user selects the value green, for example, the prop returns #0ff102.

HeaderComponent.tsx

_37
import React from 'react';
_37
_37
interface HeaderComponentProps {
_37
title: string;
_37
subtitle: string;
_37
}
_37
_37
const HeaderComponent = ({ title, subtitle }: HeaderComponentProps) => {
_37
return (
_37
<>
_37
<p>{title}</p>
_37
<p>{subtitle}</p>
_37
</>
_37
);
_37
};
_37
_37
HeaderComponent.defaultProps = {
_37
title: "VTEX",
_37
subtitle: "The Composable and Complete Commerce Platform.",
_37
};
_37
_37
HeaderComponent.schema = {
_37
title: 'Custom Component',
_37
type: 'object',
_37
properties: {
_37
title: {
_37
type: 'string',
_37
title: 'Título',
_37
},
_37
subtitle: {
_37
type: 'string',
_37
title: 'Subtítulo',
_37
},
_37
},
_37
};
_37
_37
export default CustomComponent;

Contributors
1
Photo of the contributor
+ 1 contributors
Was this helpful?
Yes
No
Suggest edits (Github)
See also
Making a custom component available in Site Editor
Guides
Contributors
1
Photo of the contributor
+ 1 contributors
On this page