Gutenberg blocks development has become a must-to-have skill for all WordPress Developers today, as a WordPress Developer who used to write PHP heavily and not so familiar with JavaScript trends and frameworks like React, you might found it confusing when you jumped into the official documentation trying to make a block that your client has asked for or maybe you were just curious and you wanted to understand how this new editor works.
I was there a few months ago, at the time I wanted to build a plugin that extends the editor with a new set of advanced blocks, it was disappointing at first, I spent long hours trying just to build a simple hello world block.
You don’t have to experience the same thing or waste so much time digging in the documentation as I did, in this tutorial, I am going to show you a step by step how you can start building your own blocks.
Prerequisites
- Basic HTML and CSS knowledge
- Basic coding experience with JavaScript and React
- Basic WordPress Knowledge
The Final Project
You will build a simple block named Hello Gutenberg that simply prints out the sentence Hello, Gutenberg!
This project is simple enough for developers who are not so familiar with React and will help them pick up the main concepts so quickly.
1. Create the Plugin
In wp-content/plugins folder create a new folder named: hello_gutenberg

Create an index.php file inside and add those lines to it:
<?php /** * Plugin Name: Hello Gutenberg - My first Gutenberg Block * Description: Simple Hello World Block * Author: douara * Author URI: https://douara.me * Version: 1.0.0 * License: GPL2+ * License URI: https://www.gnu.org/licenses/gpl-2.0.txt */ ?>
Basically, those lines define the plugin to WordPress with basic information, Plugin name, Description, Author, …etc
Hit save, and go to the plugins page on your WordPress Dashboard:

Our plugin appears on the list, hit Activate, and follow to the next step
2. Enqueueing JavaScript
To build a block in Gutenberg, we need to write javaScript, so we need to create a javaScript file and enqueue it on the backend, inside the plugin folder create a new folder named assets, within it create a file named hello-gutenberg.js and add this line to it:
alert("Hello Gutenberg!");
Go back to index.php, and let’s enqueue the script, first I am gonna create a new function that enqueues the script using wp_enqueue_script function ( follow the inline comments for more explanation )
<?php /** * Plugin Name: Hello Gutenberg - My first Gutenberg Block * Description: Simple Hello World Block * Author: douara * Author URI: https://douara.me * Version: 1.0.0 * License: GPL2+ * License URI: https://www.gnu.org/licenses/gpl-2.0.txt */ // Editor Assets CSS function hello_gutenberg_editor_assets() { // JavaScript Enqueue wp_enqueue_script( // Script name ( choose any name you want ) 'hello-gutenberg-js', // This is the url to the javaScript file plugin_dir_url(__FILE__) . 'assets/hello-gutenberg.js', // No dependencies to the script "", // This is the version of the script to enqueue, we use time function to prevent file caching the file time(), // // Enqueue in the footer true ); } ?>
Now I am gonna hook this function with a special Gutenberg action named: enqueue_block_editor_assets, basically this gonna enqueue the script only on the editor pages,
<?php /** * Plugin Name: Hello Gutenberg - My first Gutenberg Block * Description: Simple Hello World Block * Author: douara * Author URI: https://douara.me * Version: 1.0.0 * License: GPL2+ * License URI: https://www.gnu.org/licenses/gpl-2.0.txt */ // Editor Assets CSS function hello_gutenberg_editor_assets() { // JavaScript Enqueue wp_enqueue_script( // Script name ( choose any name you want ) 'hello-gutenberg-js', // This is the url to the javaScript file plugin_dir_url(__FILE__) . 'assets/hello-gutenberg.js', // No dependencies to the script "", // This is the version of the script to enqueue, we use time function to prevent file caching the file time(), // // Enqueue in the footer true ); } // Hook: Editor assets. add_action('enqueue_block_editor_assets','hello_gutenberg_editor_assets'); ?>
Now, go ahead and add a new post, you gonna get this alert:

This means that we have enqueued the script successfully, now it’s the time to define our block
3. Block Registration
Gutenberg has multiple modules that provide us with methods and components ready to be used, those modules are found on the global object wp that we can check right from the console:

We are going to start by using blocks and element modules to define our block, we can access those modules with the dot notation like so: wp.blocks and wp.element and use them in an IIFE function( Immediately Invoked Function Expression ) , I won’t go into the details of this expression now but basically this function gets executed Immediately on script load:
( function( blocks, element ) { /* * * * * We will define our block here * * * */ }( window.wp.blocks, window.wp.element ) );
Now wp.blocks and wp.element are assigned to blocks and element parameters accordingly.
To register our block we use the function registerBlockType found in the blocks module, to create the HTML elements for the block we use the createElement function found in the element module, let’s assign those to new variables:
( function( blocks, element ) { var registerBlockType = blocks.registerBlockType; var el = element.createElement; }( window.wp.blocks, window.wp.element ) );
Before Registering our block, I am gonna define its structure first by creating a paragraph element.
( function( blocks, element ) { var registerBlockType = blocks.registerBlockType; var el = element.createElement; // Block Structure var block_structure = el( 'p', // Element tag {}, // Element props ( attributes ) // Child elements ( paragraph content in this case) 'Hello Gutenberg!' ); }( window.wp.blocks, window.wp.element ) );
Note that createElement function is just a clone to the react createElement function
Next Step, Block Registration:
( function( blocks, element ) { var registerBlockType = blocks.registerBlockType; var el = element.createElement; // Block Structure var block_structure = el( 'p', // Element tag {}, // Element props ( attributes ) // Child elements ( paragraph content in this case) 'Hello Gutenberg!' ); // Block Registration registerBlockType( 'my-gutenberg-blocks/hello-gutenberg', { title: 'Hello Gutenberg', // Block Title icon: 'universal-access-alt', // Block icon category: 'layout', // Category in where the block will appear // Block structure on the editor edit: function() { return block_structure; }, // Block structure on the front-end save: function() { return block_structure; }, } ); }( window.wp.blocks, window.wp.element ) );
registerBlockType function takes two arguments, the first one is the block name ( string ), the block name should be prefixed with a namespace ( my-gutenberg-blocks in our case) but you can use anything here, the plugin name in our case is hello-gutenberg
The second argument is an object in where we define the block parameters as described inline in the code, there’re few things to include here:
Icon: you can use any WordPress icon, or you can use your own SVG.
Edit Function: Anything you return in this function will appear on the editor.
Save Function: Anything this function returns will appear on the front-end
let’s save and see how our block look like.

Now let’s add some styling to it, and to do that I am going to define a new variable name: block_style and add it as a prop to the paragraph element
( function( blocks, element ) { var registerBlockType = blocks.registerBlockType; var el = element.createElement; // Block Style block_style = { textAlign: "center", color: "#fff", backgroundColor: "#333" } // Block Structure var block_structure = el( 'p', // Element tag { style: block_style }, // Element props ( attributes ) // Child elements ( paragraph content in this case) 'Hello Gutenberg!' ); // Block Registration registerBlockType( 'my-gutenberg-blocks/hello-gutenberg', { title: 'Hello Gutenberg', // Block Title icon: 'universal-access-alt', // Block icon category: 'layout', // Category in where the block will appear // Block structure on the editor edit: function() { return block_structure; }, // Block structure on the front-end save: function() { return block_structure; }, } ); }( window.wp.blocks, window.wp.element ) );
Thank you for following until the end, if you have any questions, leave a comment below, I reply to every single comment, also, if you like the tutorial don’t forget to share it with your friends 😉