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:

  1. Add it to a page
  2. Check editor interface
  3. Verify frontend output
  4. 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.