<< All Blog Posts
Getting Started with Custom Blocks in Volto

Getting Started with Custom Blocks in Volto

Volto is the React-based frontend for Plone and will be the default frontend from Plone 6 forward. It’s highly customizable and allows content editors to assemble pages using Blocks. Specifically, this editor allows users to add, modify, reorder and delete Blocks.

Volto ships with a default set of Blocks, but did you know that you can also customize existing or create new Blocks? Here’s how I setup a custom Block from scratch using Volto (version 13.1.2).

Building a Basic Block

Each Block contains two primary components:

  • View.jsx
  • Edit.jsx

To get started, create these two files in src/components/Blocks/MyCustomBlock/:


import React from 'react';
const View = props => {
  return <div>I'm the Block view component!</div>;
export default View;


import React from 'react';
const Edit = props => {
  return <div>I'm the Block edit component!</div>;
export default Edit;

Getting Volto to recognize your Block

Next, let’s make the Block available by registering it in the blocksConfig configuration object.

There are several ways to organize your files, but I prefer to create a separate customBlocks.js file in src/components/Blocks. This provides one central location to store all of our custom Blocks. I then import the view and edit components for MyCustomBlock and define the Block using the myCustomBlock object below:

import MyCustomBlockView from '@package/components/Blocks/MyCustomBlock/View';
import MyCustomBlockEdit from '@package/components/Blocks/MyCustomBlock/Edit';
import icon from '@plone/volto/icons/list-bullet.svg';

const customBlocks = {
  myCustomBlock: {
    id: 'myCustomBlock',
    title: 'My Custom Block',
    edit: MyCustomBlockEdit,
    view: MyCustomBlockView,
    icon: icon,
    group: 'text',
    restricted: false,
    mostUsed: false,
    sidebarTab: 1,
    security: {
      addPermission: [],
      view: [],
export default customBlocks;

In src/config.js, we import customBlocks.js and add it to the blocksConfig.

We can use a spread operator to import the original settings config.block.blocksConfig and then merge it with our new custom Blocks config ...customBlocks.  

Note: You could also add customBlocks directly to  src/config.js, but having a separate file is cleaner.

import customBlocks from '@package/components/Blocks/customBlocks'


export default function applyConfig(config) {
  config.blocks = {
    blocksConfig: { 
  return config;

Now, we have a working Block.


Note: It’s important to merge the new custom Block config into the existing blocks config.  If you forget this step, the default Blocks will break displaying “Unknown block <id>” instead of content.


Enabling Blocks on your content type

To use Blocks on your content types, you need to enable the Blocks behavior through the Plone site using the following steps:

  1. Navigate to Site Setup > Dexterity Content Types and then select your content type.
  2. Navigate to the Behaviors tab.
  3. Select the Blocks behavior.
  4. Save your changes.


This can also be done programmatically via GenericSetup: 

<?xml version="1.0" encoding="utf-8"?>
<object name="custom_content_type" meta_type="Dexterity FTI"
   i18n:domain="plone" xmlns:i18n="http://xml.zope.org/namespaces/i18n">
 <property name="behaviors">
  <element value="volto.blocks"/>

Next Steps

We’ve set up the basic structure for our Block, made Volto aware of it and made it available on the content type. Now you can build out the Edit component functionality or enhance your Block with Extensions.

Tips for Learning Volto

Share your Volto projects with us, and schedule a free consult today! 

Thanks for filling out the form! A Six Feet Up representative will be in contact with you soon.

Connect with us