This is the first part of our Gutenberg Custom Block Development tutorial series, if you haven’t read our introduction article I highly recommend you to read it then continue with this one. In this article, we are going to learn how we can create a custom block for Gutenberg Block Editor from scratch. We have made this article for the absolute beginners and explained every single piece of code we have written so you can easily follow along with us. So without wasting any time let’s get straight to it.
Table of Contents
Objective
First thing first let’s take a look at what we are trying to build? In this article, we are going to take a look at the building process of a custom paragraph block. As you can see in the image below, in this custom block we’ll have a simple “Hello World!” text.
For now, it’s not editable, this is just a static custom block and everything will be hardcoded. Later in the upcoming articles, we will take a look at how we can create things editable and make multiple variations of them. We have intentionally not added editing capabilities to keep things simple to understand, if we progress gradually then understanding it will be a lot easier.
Prerequisites for Custom Block
Now let’s take a look at what are prerequisites before starting to create custom blocks.
Environment
For developing a custom block you should have a local test website running on your system, along with a node and a code editor installed.
Before continuing make sure you have Gutenberg Development Environment ready for developing custom block if not then head over to the How to Setup Gutenberg Development Environment article and set up the environment into your local machine. After setting up the environment continue with this article.
In my setup, I am using XAMPP(You can use any) to run the local server and I have a clean WordPress installation with the latest version 5.8.1, if you are on a later version no worries most probably the codes will work the same if not drop a comment we will update it. I have uninstalled all the preinstalled plugins and using the WordPress Twenty Twenty-One theme.
We have also enabled debug mode for our website for easier debugging. If you don’t know how to do that head over to this link to know how to do it.
Languages
In this article, we are going to use HTML, CSS, PHP, and JavaScript. Most of our code will be in JavaScript since the new Gutenberg is based on React which is a JavaScript library so if you don’t have a knowledge of JavaScript you should take a look at it.
All the codes we have used in this tutorial will be available on our Github repository, you can check our repo for complete code.
Step 1: Create a plugin
The first step of creating a custom block is to create a plugin for it. You can have multiple blocks in the same plugin but at least one plugin is required for creating a custom block. To create a plugin go to your WordPress installation folder and navigate to wp-content/plugins/
since I am on XAMPP my plugins directory is at C:\xampp\htdocs\wordpress\wp-content\plugins
your’s will be according to your local environment.
In this directory create a new folder and name it whatever you want, I am naming mine WPT Custom Blocks and save it. Now open this folder into your code editor, for VS Code you can right-click on the folder and select open with VS Code.
Now from the code editor create a new PHP file and name it whatever you like, I am naming mine plugin.php
. Now first right open PHP tag<?php
then in documented comment add details about your plugin.
<?php /** * Plugin Name: WPT Custom Blocks * Plugin URI: https://github.com/ * Description: A Custom block created for learnirng by WebProTime team. * Version: 1.0.0 * Author: WebProTime * */
As you can see in the above example we at least need to add a few things Plugin Name, Plugin URI, Description, Version, and Author. These details are the details shown in the WordPress plugin section and at least the name and version are required.
Without a name and version, WordPress won’t consider your file a plugin and it won’t work. After adding these details, go to your browser and open your local website. From your local website’s dashboard navigate to the plugin section in the list you’ll see your created plugin name.
These comments must need to be just after the PHP opening tag and make sure no code, text, or comment is written before this else the plugin will not work.
Click on activate to activate the plugin, after successfully activating it comes back to our code editor and starts writing the code now.
Step 2: Create a Function
Now let’s create a function for registering our custom block, to create a function in PHP first we will use a keyword function and then write the name of our function as shown in the code example below.
function wpt_register_blocks() { //code inside }
After creating a function first thing we will do is to check if Gutenberg is active on the website or not. To check if Gutenberg is active we need to call the following function function_exists( 'register_block_type' )
if it exists we will continue or else we return since without Gutenberg it is worthless to continue.
// Check if Gutenberg is active. if ( ! function_exists( 'register_block_type' ) ) { return; }
You can use the above code to check if Gutenberg is active and if not return and close the execution of the code.
Step 3: Create Block File
Now the next step is to create a JavaScript file for actually writing the code for our first block. Since we have not talked about ES Next yet we will write our first block code in ES5, don’t worry if ES Next and ES5 confusing you we have a dedicated section just for that in our upcoming articles.
Now first thing first creates a folder inside your plugin folder, you can name it anything I am naming it wpt-blocks
and then create a file wpt-blocks.js
you can name accordingly. In VS code file should open automatically now let’s write actual code into it.
Step 4: Create a self-invoking function
First, we will create a self-invoking function with two parameters blocks, element
and for these parameters, the value will be windows.wp.blocks, windows.wp.element
notice we are using wp
package here that package provides functionality for our blocks. So let’s know more about them.
( function( blocks, element) { //Code goes here })( window.wp.blocks, window.wp.element);
The wp
package
When we are writing in JavaScript enqueued in Gutenberg editor we have access to a wp
package. This is a huge package or you can say an object that has a whole bunch of useful components and functions that we can use for creating blocks. While coding for custom blocks we are going to use wp
the package quite a lot.
For example, to register a block we can use wp
package’s blocks.registerBlockType
function to register a block.
Step 5: Register a Block
The next step is to register a block, to register a block we will use registerBlockType()
function available in wp.blocks
to register the block, this function requires two parameters; the first parameter is a string that will have a namespace and a name of the block, and the second parameter will be an object with the complete configuration of the block.
In the first parameter, Gutenberg expects all blocks to have a namespace so id didn’t conflict with the other blocks with the same name, and the namespace and the name should be separated with a /
forward slash. For example, I am creating a block name wpt-block
but possibles other plugins or themes can also have a block name test so we use wpt
namespace and write wpt/wpt-block
for our first parameter so it won’t conflict with other blocks with the same name. One thing to note is our namespace won’t be visible in the frontend and you won’t see it on your site.
The actual code of registering a block will look like this as shown below.
( function( blocks, element) { // Registering A Block blocks.registerBlockType('wpt/wpt-block', { // block configuration code will go here as object } })( window.wp.blocks, window.wp.element);
In the second parameter, we will add the complete configuration of our block. In the configuration object, we need to add few things some are required some are not. Since we are working with an object we’ll add everything in key-value pair and every pair will be separated with the ,
comma. There are many properties so let’s take a look at them one by one.
title (required)
The first and required property is the title, as the name suggests we will write the title of our block in this property. We can use string value here means you can type anything and spaces are also allowed here. For example, our block title will WPT Custom Block,
.
title: 'WPT Custom Block',
category (required)
The second and required property will be the category of the block, this property will be used to determine in which category your block will be added. By default, there are five possible values available for this property common
,formatting
,layout
,widgetsc
, and embed
.
Do note that it is possible to create our own custom category for our block and we will learn how to do that in upcoming articles.
category: 'common',
icon (optional)
The next thing we can that is optional is the icon for our block, we can use dashicon as an icon or even add our own custom SVG as an icon. For now, we will be using dashicon in this article later in upcoming articles we will see how we can use SVGs.
For using a dashicon we don’t need anything extra just simply need to add the name of it like shown in the code below.
icon: superhero, //superhero is a dashicon name
You can see the complete list of dashicon in this link and use any as per your need.
Since it’s optional if you don’t add this no icon will be assigned as your block icon and it will be empty.
description (optional)
The next property is a description that is optional, we can add a description of our block as a text string. When you select your block you’ll see the description of your block in Gutenberg Block Editor. You can write descriptions as shown in the code below.
description: 'First Hello World Block',
keywords (optional)
Another options property for the block is the keyword. Gutenberg Block Editor provides search functionality for the blocks, you can add keywords for your block so in search anyone search for the block with keywords then it will still show up. Without keywords, blocks can only be searched with their exact name.
To add keywords we can add string tags in arrays, For the demo, I am adding test
and searchme
in our block as shown below.
keyword: ['test', 'searchme'],
attributes (optional)
Another optional property for the block attributes, even though it’s optional except for this example we are going to use it in every single other block tutorial. The attributes are one of the most important parts of blocks, this is where we store our structure of blocks and users inputs.
Edit and Save (Kinda required)
When we register a block edit and save property is actually a function that expects something to return, the edit and save functions actually provide the interface that how blocks will be rendered in the block editor, how the block will work and be modified, and how it will be saved and shown on the website.
Edit function
Edit function is kind of required you can skip this but if you skip this your code won’t break and you won’t receive any error but you won’t see anything on the editor so consider it required. The edit function is used to structure or design the block in the editor. On a high level consider what you code or design in the edit function will be visible on the block editor. You will also use the edit function to take inputs and use it for updating the blocks.
Save function
The save function is optional but also kind of required because the save function handles two things one how your block will look on the published page or post and how the created block will be saved in the database. Also, keep in mind that you don’t update or edit the data in the save function, it is only used for outputting the data. On the high level, you can say the save function determines how your block will render in a published post or page.
Another thing to keep in mind is that you are highly likely to see an error in the block editor while editing something in the save function as show in the image below, this happens because Gutenberg expects the content should not change so after making any changes if you see this don’t panic your code isn’t broken just hit F5
or Win + R
to reload the page it should work fine. But even that doesn’t work then just remove the block and re-add it. And if that doesn’t work then your code is broken:)
I know it’s annoying, hopefully, WordPress will fix this issue in the following update.
To see the actual difference and better understand the edit and save function we will gonna use two different texts in both functions and we will see how they render in the editor and published page.
For the edit function, we will return p
tag with the text “Hello World! Edit!”.
For the save function, we will return p
tag with the text “Hello World! Save!”.
Now when we use this block in the actual website in the editor text will be “Hello World! Edit!” but on the published page text will be “Hello World! Save!” as you can see in the image above. This demo will give you a better idea of how edit and save functions works.
Note: Keep in mind we have used two different types of returns just for understanding in the real block you must never show different outputs because it can confuse users.
Other properties
There are also several different properties such as registerBlockType
, parent
, supports
, transforms
, example
, and styles
these can be used for some advance blocks, we are currently ignoring them because that can create some confusion we will see learn more about them and see their usages in upcoming tutorials for now just focus on the above ones.
The complete block code
Now below you can see the complete code of our JavaScript file, we have used the wp
package and created a self-invoke JS function and inside that function registered a block with its name and properties and the complete code will look like the code given below.
//wpt-blocks.js ( function( blocks, element) { var el = element.createElement; // Registering A Block blocks.registerBlockType('wpt/wpt-block', { title: 'WP Custom Block', category: 'common', icon: 'superhero', description: 'First Hello World Block', keyword: ['test', 'searchme'], // Block Edit Function edit: function() { return el('p', null ,'Hello World! Edit!') }, //Block Save Function save: function() { return el('p', null ,'Hello World! Save!') }, } ); })( window.wp.blocks, window.wp.element);
One extra thing that you may have noticed in the code that we haven’t talked above is a variable var el = element.createElement;
that variable is just an easier way of referencing of element.createElement
. You already know about it if you have used JS before.
Step 6: Register script in PHP
Now let’s go back to our PHP code where we have created our plugin and created a function to register the block. After checking if Gutenberg is enabled we will first register our script file aka the plugin that we have created wpt-block.js
. We will use wp_register_script()
function to register our script. In this function first, we will block the name string then the path of the block script, and at last requirement of the block in an array.
// Add block script. wp_register_script( 'wpt-block', plugins_url( 'wpt-block/wpt-block.js', __FILE__ ), ['wp-blocks'] );
Step 7: Register block in PHP
The next part is to register the custom block in PHP to register this block we will use register_block_type()
function, this function expects two arguments. In the first argument, we will add namespace and the name of the block that we have created in the JS file, make sure namespace and name are exactly the same as JS file.
In the second argument, we can use quite a few arguments but for now, we will only use one editor_script
. This argument is very important in this argument we will provide the handle(the first parameter of wp_register_script()
function)
Step 8: Call PHP function
The last step will be to hook the PHP function so it will get called when required. To do that we will use add_action()
function, in which we will pass two arguments first 'init'
and the second name of the PHP function in our case wpt_register_blocks()
.
The complete PHP code will be like shown below:
<?php /** * Plugin Name: WPT Custom Blocks * Plugin URI: https://github.com/ * Description: A Custom block created for learnirng by WebProTime team. * Version: 1.0.0 * Author: WebProTime * */ function wpt_register_blocks() { // Check if Gutenberg is active. if ( ! function_exists( 'register_block_type' ) ) { return; } // Add block script. wp_register_script( 'wpt-block', plugins_url( 'wpt-block/wpt-block.js', __FILE__ ), ['wp-blocks'] ); // Register block script and style. register_block_type( 'wpt/wpt-block', [ 'editor_script' => 'wpt-block', ] ); } add_action( 'init', 'wpt_register_blocks' );
And with that, we have created our first custom block successfully.
Step 9: Test the Block
Now the last thing is to check the fruit of our labor how the block is displaying on the page. You can see mine in the video below.
Conclusion
Now we have successfully created our first custom block and I believe now you understand how blocks work, if you have any doubts or questions or having trouble in building the block make sure to comment down below I’ll try to answer all your question.
You can get the complete source code used in this article and in the complete series on my Github repo.
The custom block development is not over yet we have more articles on coding custom blocks, make sure to read them too to fully understand how to make blocks. We are starting with the basics and going to advance so you can adapt easily even if you are a beginner so make sure to bookmark and read upcoming articles on this topic.
While you are here we have some more great articles on Gutenberg Block Editor make sure to check them out too.