Last modified: May 05, 2025 By Alexander Williams
Custom Volto Blocks for Plone 6
Volto is the modern frontend for Plone 6. It uses React and provides a block-based editor. This guide will show you how to create custom Volto blocks.
What Are Volto Blocks?
Volto blocks are reusable components. They let editors build pages visually. Each block has its own settings and styles.
Blocks can display text, images, or complex data. You can find built-in blocks in the Blocks Editor.
Prerequisites
Before creating custom blocks, you need:
- Plone 6 backend setup
- Volto frontend installed
- Basic React knowledge
- Node.js and yarn
For theming, check Modern Plone Themes with Bootstrap & React.
Block Structure
A Volto block has these main parts:
- Schema: Defines block settings
- Edit component: Editor interface
- View component: Display output
Creating a Simple Block
Let's create a "Message" block that shows styled text.
First, create a new component in your Volto add-on:
// src/components/Blocks/Message/index.js
import React from 'react';
import { defineMessages } from 'react-intl';
const messages = defineMessages({
title: {
id: 'Message',
defaultMessage: 'Message Block',
},
});
const MessageEdit = (props) => {
return <div>Message Block Editor</div>;
};
const MessageView = (props) => {
return <div>Message Block Output</div>;
};
export { MessageEdit, MessageView, messages };
Registering the Block
Add your block to Volto's configuration:
// src/config.js
import { MessageEdit, MessageView, messages } from './components/Blocks/Message';
export const blocks = {
message: {
id: 'message',
title: messages.title,
edit: MessageEdit,
view: MessageView,
restricted: false,
mostUsed: true,
blockHasOwnFocusManagement: false,
},
};
Adding Block Schema
The schema defines editable fields. Use SchemaEnhancer
to extend it:
// src/components/Blocks/Message/schema.js
import { defineMessages } from 'react-intl';
export const MessageSchema = (props) => {
return {
fieldsets: [
{
id: 'default',
title: 'Default',
fields: ['text', 'style'],
},
],
properties: {
text: {
title: 'Message text',
widget: 'textarea',
},
style: {
title: 'Style',
choices: [
['info', 'Info'],
['warning', 'Warning'],
],
},
},
required: [],
};
};
Complete Block Example
Here's the full implementation with schema:
// src/components/Blocks/Message/index.js
import React from 'react';
import { defineMessages } from 'react-intl';
import { MessageSchema } from './schema';
const messages = defineMessages({
title: {
id: 'Message',
defaultMessage: 'Message Block',
},
});
const MessageEdit = (props) => {
const { data, onChangeBlock } = props;
return (
<div className={`message-block ${data.style}`}>
<textarea
value={data.text}
onChange={(e) => onChangeBlock(props.block, {
...data,
text: e.target.value,
})}
/>
</div>
);
};
const MessageView = (props) => {
const { data } = props;
return (
<div className={`message-block ${data.style}`}>
{data.text}
</div>
);
};
export { MessageEdit, MessageView, messages, MessageSchema };
Styling Your Block
Add CSS for your block in the component:
// src/components/Blocks/Message/style.css
.message-block {
padding: 1rem;
margin: 1rem 0;
}
.message-block.info {
background: lightblue;
}
.message-block.warning {
background: lightyellow;
}
Advanced Block Features
For complex blocks, you might need:
- Custom widgets
- Server-side data
- Block variations
For data handling, see Build RESTful APIs with Plone.
Testing Your Block
Always test your block:
- Add it to a page
- Check editor interface
- Verify frontend output
- Test different settings
Best Practices
Follow these tips for better blocks:
- Keep components small
- Use meaningful names
- Add propTypes
- Include documentation
For more component patterns, read Plone View Components Guide.
Conclusion
Custom Volto blocks extend Plone's editing experience. They let you create tailored components for your site.
Start with simple blocks and gradually add complexity. Remember to test thoroughly and document your work.
With these techniques, you can build powerful frontend components for Plone 6.