Slider Block
A carousel/slider that cycles through slides. Slides are stored as an object_list — each slide has a title, description, image, and optional button.
Developer Reference
Schema
Pass this object inside the blocks option when calling initBridge() to register this block type with the admin UI. See Custom Blocks for the full setup guide.
slider: {
id: 'slider',
title: 'Slider',
icon: sliderIcon,
group: 'common',
schemaEnhancer: {
inheritSchemaFrom: {
defaultsField: 'itemDefaults',
},
},
blockSchema: {
fieldsets: [
{
id: 'default',
title: 'Default',
fields: ['slides', 'variation', 'autoplayEnabled', 'autoplayDelay', 'autoplayJump', 'headline', 'headlineTag'],
},
],
properties: {
headline: { title: 'Headline', type: 'string' },
headlineTag: { title: 'Headline tag', widget: 'select', choices: [['h1','h1'],['h2','h2'],['h3','h3'],['h4','h4'],['h5','h5'],['h6','h6']] },
slides: {
title: 'Slides',
widget: 'object_list',
itemTypeField: 'variation', // sync trigger — names the sibling field
allowedBlocks: ['slide', 'image', 'listing', 'teaser'],
typeField: '@type',
defaultBlockType: 'slide',
},
variation: {
title: 'Item Type',
widget: 'blockTypeSelect',
},
autoplayEnabled: {
title: 'Autoplay Enabled',
type: 'boolean',
default: false,
},
autoplayDelay: {
title: 'Autoplay Delay',
type: 'integer',
default: 4000,
},
autoplayJump: {
title: 'Autoplay Jump',
type: 'boolean',
default: false,
},
},
required: [],
},
}JSON Block Data
Example block JSON (as stored in the CMS). This is the data structure your component will receive in the block prop.
{
"@type": "slider",
"autoplayEnabled": false,
"autoplayDelay": 5000,
"slides": [
{
"@type": "slide",
"title": "Product Launch 2025",
"head_title": "New Release",
"description": "Discover our latest innovations.",
"buttonText": "Learn More",
"preview_image": [
{
"@id": "data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 width=%27800%27 height=%27400%27%3E%3Crect width=%27100%25%27 height=%27100%25%27 fill=%27%235577aa%27/%3E%3Ctext x=%2750%25%27 y=%2750%25%27 fill=%27white%27 text-anchor=%27middle%27 font-size=%2724%27%3ESlide 1%3C/text%3E%3C/svg%3E"
}
]
},
{
"@type": "slide",
"hideButton": true,
"title": "Award-Winning Design",
"head_title": "Featured",
"description": "Recognized for excellence in UX.",
"buttonText": "See Details",
"preview_image": [
{
"@id": "data:image/svg+xml,%3Csvg xmlns=%27http://www.w3.org/2000/svg%27 width=%27800%27 height=%27400%27%3E%3Crect width=%27100%25%27 height=%27100%25%27 fill=%27%23aa5577%27/%3E%3Ctext x=%2750%25%27 y=%2750%25%27 fill=%27white%27 text-anchor=%27middle%27 font-size=%2724%27%3ESlide 2%3C/text%3E%3C/svg%3E"
}
]
}
]
}Rendering
How this block renders in your frontend. Add its handling to your renderer, or — for list-style blocks — register a fetcher and reuse your list rendering.
import { getImageUrl } from './utils.js';
function SliderBlock({ block }) {
const [current, setCurrent] = useState(0);
const slides = expandTemplatesSync(block.slides || [], { idField: '@id' });
return (
<div data-block-uid={block['@uid']} className="slider-block">
{slides.map((slide, i) => (
<div
key={slide['@id']}
data-block-uid={slide['@id']}
className="slide"
style={{ display: i === current ? 'block' : 'none' }}
>
{slide.preview_image && (
<img
data-edit-media="preview_image"
src={getImageUrl(slide.preview_image)}
alt=""
/>
)}
<span data-edit-text="head_title">{slide.head_title}</span>
<h2 data-edit-text="title">{slide.title}</h2>
<p data-edit-text="description">{slide.description}</p>
<button data-edit-text="buttonText">{slide.buttonText}</button>
</div>
))}
<div className="slider-dots">
{slides.map((_, i) => (
<button key={i} onClick={() => setCurrent(i)} className={i === current ? 'active' : ''} />
))}
</div>
</div>
);
}