How to Create a Custom Gutenberg Block in WP (Step-by-Step)

Creating a custom Gutenberg block in WordPress is essential for developers who want to extend the WordPress block editor’s functionality beyond what’s available by default. Gutenberg (the block editor introduced in WordPress 5.0) uses React.js under the hood, and creating a custom block typically involves writing both PHP and JavaScript (mainly ESN ext + JSX). With the Gutenberg (block) editor becoming the default in WordPress, building custom blocks can greatly enhance the editing experience.

In this guide, you’ll learn how to create a custom Gutenberg block using JavaScript and PHP.4q wp-content/plugins/my-custom-block/

 

Step 1: Create a my-custom-block.php file:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
<?php
/**
* Plugin Name: My Custom Block
*/
function my_custom_block_register_block() {
wp_register_script(
'my-custom-block-editor',
plugins_url('block.js', __FILE__),
array('wp-blocks', 'wp-element', 'wp-editor'),
time(),
);
}
add_action('init', 'my_custom_block_register_block');
?>
<?php /** * Plugin Name: My Custom Block */ function my_custom_block_register_block() { wp_register_script( 'my-custom-block-editor', plugins_url('block.js', __FILE__), array('wp-blocks', 'wp-element', 'wp-editor'), time(), ); } add_action('init', 'my_custom_block_register_block'); ?>
<?php
/**
 * Plugin Name: My Custom Block
 */

function my_custom_block_register_block() {
    wp_register_script(
        'my-custom-block-editor',
        plugins_url('block.js', __FILE__),
        array('wp-blocks', 'wp-element', 'wp-editor'),
        time(),
    );
   
}
add_action('init', 'my_custom_block_register_block');
?>

Step 2: Create the Block JavaScript File

Create a block.js in the same folder.

Basic block example:
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const { registerBlockType } = wp.blocks;
const { RichText } = wp.blockEditor;
registerBlockType('myplugin/my-custom-block', {
title: 'My Custom Block',
icon: 'smiley',
category: 'common',
attributes: {
content: {
type: 'string',
source: 'html',
selector: 'p',
},
},
edit: function (props) {
return wp.element.createElement(RichText, {
tagName: 'p',
value: props.attributes.content,
onChange: function (content) {
props.setAttributes({ content: content });
},
placeholder: 'Write something...',
});
},
save: function (props) {
return wp.element.createElement(RichText.Content, {
tagName: 'p',
value: props.attributes.content,
});
},
});
const { registerBlockType } = wp.blocks; const { RichText } = wp.blockEditor; registerBlockType('myplugin/my-custom-block', { title: 'My Custom Block', icon: 'smiley', category: 'common', attributes: { content: { type: 'string', source: 'html', selector: 'p', }, }, edit: function (props) { return wp.element.createElement(RichText, { tagName: 'p', value: props.attributes.content, onChange: function (content) { props.setAttributes({ content: content }); }, placeholder: 'Write something...', }); }, save: function (props) { return wp.element.createElement(RichText.Content, { tagName: 'p', value: props.attributes.content, }); }, });
const { registerBlockType } = wp.blocks;
const { RichText } = wp.blockEditor;

registerBlockType('myplugin/my-custom-block', {
  title: 'My Custom Block',
  icon: 'smiley',
  category: 'common',
  attributes: {
    content: {
      type: 'string',
      source: 'html',
      selector: 'p',
    },
  },
  edit: function (props) {
    return wp.element.createElement(RichText, {
      tagName: 'p',
      value: props.attributes.content,
      onChange: function (content) {
        props.setAttributes({ content: content });
      },
      placeholder: 'Write something...',
    });
  },
  save: function (props) {
    return wp.element.createElement(RichText.Content, {
      tagName: 'p',
      value: props.attributes.content,
    });
  },
});
This creates a basic block that lets you enter and display rich text content.

Step 3: Add Block Styling (Optional)

Add a style.css and editor.css file to style your block on both the front end and backend.

Then enqueue them in your PHP:
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
wp_register_style(
'my-custom-block-editor-style',
plugins_url('css/editor.css', __FILE__),
array(),
time()
);
wp_register_style(
'my-custom-block-style',
plugins_url('css/style.css', __FILE__),
array(),
time()
);
register_block_type('myplugin/my-custom-block', array(
'editor_script' => 'my-custom-block-editor',
'editor_style' => 'my-custom-block-editor-style',
'style' => 'my-custom-block-style',
));
wp_register_style( 'my-custom-block-editor-style', plugins_url('css/editor.css', __FILE__), array(), time() ); wp_register_style( 'my-custom-block-style', plugins_url('css/style.css', __FILE__), array(), time() ); register_block_type('myplugin/my-custom-block', array( 'editor_script' => 'my-custom-block-editor', 'editor_style' => 'my-custom-block-editor-style', 'style' => 'my-custom-block-style', ));
wp_register_style(
       'my-custom-block-editor-style',
       plugins_url('css/editor.css', __FILE__),
       array(),
       time()
   );
   
   wp_register_style(
       'my-custom-block-style',
       plugins_url('css/style.css', __FILE__),
       array(),
       time()
   );
   register_block_type('myplugin/my-custom-block', array(
       'editor_script' => 'my-custom-block-editor',
       'editor_style'  => 'my-custom-block-editor-style',
       'style'         => 'my-custom-block-style',
       
   ));

Step 4: Test It Out

Go to your WordPress admin dashboard.

Activate the “My Custom Block” plugin.

Create or edit a post or page.

w3
Add the “My Custom Block” from the block inserter.

Type some text and publish the page.

Conclusion

Custom Gutenberg blocks allow for highly tailored content creation experiences on WordPress. Once you’re familiar with the basics, you can add:

Custom block controls

Server-side rendering (render_callback)

Leave a Reply