Develop your own WordPress block - Part 3: Register WordPress block with registerBlockType

In this series of articles, I'll explain how you can build your own WordPress block from scratch. In the third part we look at the registerBlockType function, which you can use to register your WordPress block and add it in the Gutenberg editor.

At the start of the series and first part is here .

Create files for new WordPress block

After we have created our plug-in with the Create Guten Block Toolkit in the second part , we can now start developing our example - an Image Card Block.

We create a new folder / image-card in the source directory. In it we create two new and empty files: index.js and style.css . We're practically starting from scratch, which is why you can delete the existing example block of the CGB toolkit.

The src directory should now have the following structure:

 ├── src | ├── image-card | | ├── index.js | | └── style.scss | | | ├── blocks.js | ├── common.scss | └── init.php

Then we open the file /src/blocks.js and import our new block:

 import './image-card/index.js';

This will read the newly created index.js from Webpack and we can register and develop our new WordPress block there. If your plugin should contain further blocks, you can simply create further folders for additional blocks in the src directory.

The registerBlockType function at a glance

Each block is registered in the editor with the registerBlockType () function. The function is provided to us by the package wp-blocks and takes two parameters:

  • name string : block name.
  • settings Object : Block Settings.
 registerBlockType( 'my-plugin/block-name', {} );

First, a unique string must be passed that identifies the block. For this, the name is usually structured with namespace/block-name and the slug of the WordPress plugin is used as the namespace. In our case it is themecoder-block/image-card .

The configuration or settings object, which is passed as the second argument, is much more interesting. In this object we define all the properties and functions that distinguish our block and make it functional.

The most important properties for the block settings are:

  • title string : The displayed name of the block in the editor.
  • category string : To which category in the block inserter the block belongs.
  • attributes Object : declaration of all data or variables of the block.
  • edit function : Describes how the block is rendered and displayed in the editor.
  • save function : Describes how the block is displayed in the frontend.

There are of course a lot of other properties for the Settings Object, which we will deal with in more detail.

It is important to know at this point that our complete block is defined with the Settings Object. The object contains all properties, attributes and functions of the block and is passed as a second parameter to registerBlockType() .

Register Image Card WordPress Block

Enough of theory. It's time to write some code and create our block.

You can add the following code to the /src/image-card/index.js file:

 /** * Register block */ wp.blocks.registerBlockType( 'themecoder-block/image-card', { title: wp.i18n.__( 'Image Card', 'themecoder-block' ), category: 'layout', edit() { return ( <div>Block Content im Editor</div> ); }, save() { return ( <div>Block Content im Frontend</div> ); }, } );

We register our block with wp.blocks.registerBlockType() and define a title, a category and the edit and save functions in our settings. These do not return HTML, but JSX, which is why quotation marks for strings are not necessary here.

and that's it.

You should now be able to find and insert the Image Card Block in the Block Inserter:

Block inserter

Tip: Make sure that you have started Webpack with npm start in case the block is missing.

The WordPress packages in the Gutenberg Editor

WordPress Core has provided us with a number of packages for developing blocks since version 5.0. These are now also available as NPM packages, e.g. @ wordpress / blocks .

To develop blocks, we don't have to install them as external node modules. The Gutenberg Editor kindly provides us with (almost) all packages in the global variable wp , which contains all components and functions as a huge object.

The most important packages for our purposes are:

  • wp.element - Abstraction Layer from WordPress for React and ReactDOM.
  • wp.blocks - Mainly functions for creating and manipulating blocks.
  • wp.components - General components for common UI elements.
  • wp.editor - More specific components for UI elements in the Gutenberg Editor.
  • wp.i18n - Contains all localization functions for translating text strings.
  • - functions to interact with the Redux data stores of WordPress.

Typing the complete path to a function ( wp.blocks.registerBlockType ) would be a bit tedious in the long run, which is why we make use of an ES6 feature called Destructuring . With the object destructuring of the WP packages, we only extract the functions currently required from the global wp object and make them accessible as variables.

We can adjust our code above a bit accordingly and make it clearer:

 /** * WordPress dependencies */ const { registerBlockType } = wp.blocks; const { __ } = wp.i18n; /** * Register block */ registerBlockType( 'themecoder-block/image-card', { title: __( 'Image Card', 'themecoder-block' ), category: 'layout', edit() { return ( <div>Block Content im Editor</div> ); }, save() { return ( <div>Block Content im Frontend</div> ); }, } );

We encounter destructuring very often when developing with React and Gutenberg Blocks. If you are not yet familiar with modern JavaScript, I recommend Googling the term and reading some tutorials, for example the Destructuring Guide from codeburst .

Create HTML markup for Image Card Block

After we have registered our block in the editor, we can now create the basic HTML structure for our image card. The block will later display image and text in two columns, which is why we are creating some div elements for this structure.

You should note that we are still writing JSX and not HTML here, which leads to some differences. The term class is registered in JavaScript for classes, which is why className is used in JSX to identify the class attribute in HTML elements.

We start by changing the save function of our WordPress block:

 save() { return ( <div> <div className="tc-columns"> <div className="tc-image"> </div> <div className="tc-card"> <h2>Titel des Blocks</h2> <p>Beschreibung des Blocks.</p> </div> </div> </div> ); },

The first div element is our block wrapper. The CSS class of the block is automatically inserted for the save function, so that we as developers can do without it. The class is generated from the prefix wp-block, the namespace and name of the block. In our case, the full name is wp-block-themecoder-block-image-card .

In the edit function for rendering the block in the editor, the CSS class is not automatically added. For this reason, we add these manually. We get the class with the variable className from the props argument. We use destructuring again for this.

 edit( props ) { const { className } = props; return ( <div className={ className }> <div className="tc-columns"> <div className="tc-image"> </div> <div className="tc-card"> <h2>Titel des Blocks</h2> <p>Beschreibung des Blocks.</p> </div> </div> </div> ); },

As mentioned briefly in Part 1 , React relies on components that are nested within one another. Input variables can be transferred from the parent component to child components in the form of the props argument. Props stands for properties and is an object that can contain any number of variables.

WordPress blocks also have a props object, which is available as a parameter for the save and edit function of a block. For testing console.log( props ) you can use the edit function to console.log( props ) the props with console.log( props ) in the browser console in order to get an overview of all props of the block. You should get an object with similar variables:

 props: { attributes: {}, className: "wp-block-themecoder-block-image-card", clientId: "6b0366da-11af-45f2-9af0-4080415e5eed", isSelected: false, name: "themecoder-block/image-card", [...] }

For the development of custom blocks, we will later very often need the property attributes , in which all data and options of the block are saved. The object is currently empty because we have not yet defined any block attributes.

Add styling for WordPress block

As the last step for today, let's add some styling for our WordPress block. To do this, we first import our style.scss , based on the index.js of our block. You can paste the code above the registerBlockType () function:

 /** * Internal dependencies */ import './style.scss';

In the style.scss we can now style our WordPress block. For our purposes, a few spaces and a little drop shadow are sufficient. We implement the two-column layout with Flexbox.

 .wp-block-themecoder-block-image-card { margin-bottom: 1.5em; box-shadow: 0 0 10px #ccc; .tc-columns { display: flex; .tc-image { width: 50%; background: #eee; } .tc-card { width: 50%; padding: 4em 2em; h2 { margin-top: 0; } p { margin-bottom: 0; } } } }

So that it remains manageable for the tutorial, we do without responsive design, ie the block remains in two columns even on smaller screens.

Result and outlook for part 4

As a result you should now get this block, which is of course still completely static.

Image Card Block Part 3

You can find the complete code of our WordPress block on Github and you can also clone and install the repo from there. I will publish the current status as a new block for each part of the tutorial so that you can follow all steps at any time.


In the next part we will add input fields with the RichText component to make the title and description of the block editable. Then it continues with media upload and toolbar and sidebar options for the block.

Overview of all articles in this series