WordPress recently introduced @wordpress/scripts
npm package. It is a collection of reusable scripts for WordPress Development. We will learn about how to create a Custom Gutenberg block using ES6
, JSX
and @wordpress/scripts
package.
Since most browsers cannot support or run ES6
and JSX
, we need to use tools Babel
to transform these syntaxes, to the code that browsers can understand. Also by using a build tool like Webpack
, we can organize our code into smaller modules and then bundle them together into a single download.
The @wordpress/scripts package abstracts these libraries away to standardize and simplify development, so you won’t need to handle the details for configuring those libraries.
Before Starting Development
- We need WordPress development environment
- JavaScript build tools (node/npm) if using React/JSX
Create directory for Gutenberg Block in plugins directory
Create a new directory in wordpress/wp-content/plugins with name myFirst-block and install @wordpress/scripts
package using npm inside of it. The — save-exact
installs the exact version of the @wordpress/scripts
package
cd wordpress/wp-content/plugins mkdir myFirst-block cd myFirst-block npm init npm i --save-dev --save-exact @wordpress/scripts
This will install all required packages and dependencies inside a node_modules directory. Please note that src/index.js will be its entry point and output build file will be in build/index.js
So also create two directories in myFirst-block directory as src and build
This is a CLI and exposes a binary called wp-scripts
so we can call it directly. So we will add these script in the package.json
"scripts": { "start": "wp-scripts start", "build": "wp-scripts build" },
When we run
npm run start then wp-scripts will run in watch mode So if we make changes in src/index.js then it will automatically create build file for it real time
Create plugin file to Register Block in plugin
We need to register our block server-side to ensure that the script is enqueued when the editor loads, Now we create a plugin file to enquee styles and scripts build/index.js to our block
<?php /* Plugin Name: myFirst-block Author: webkul */ function myFirst-block() { $styleURI = plugin_dir_url( __FILE__ ).'/src/style.css'; //Enquee style wp_enqueue_style( 'myFirst-block-style', $styleURI, ); // Register JavasScript File build/index.js wp_register_script( 'myFirstblock', plugins_url( 'build/index.js', __FILE__ ), array( 'wp-blocks', 'wp-element', 'wp-editor' ), ); // Register editor style src/editor.css wp_register_style( 'myFirst-block-editor-style', plugins_url( 'src/editor.css', __FILE__ ), ); // Register block register_block_type( 'gutenreact/myFirst-block', array( 'editor_script' => 'myFirstblock', 'editor_style' => 'myFirst-block-editor-style', ) ); } add_action( 'init', 'myFirst-block' );
Now we need to create index.js file in src directory, this will be our entry point.
In index.js we can register a block with registerBlockType()
function, registerBlockType will take two arguments.
- Block name : This is a unique identify string for our Block.
- Object(Array) : This is a configuration object of our Block. Object [ { key: value } ]
// Registering my first block with a unique name registerBlockType( 'myCustomBlock/my-first-block', {} );
namespace is the name of our theme or plugin.
This name is used on the comment delimiters as <!-- wp:namespace/block-name -->
when the post is saved into the database.
Now we are going to register our first block using registerBlockType()
function. Here myFirst-block is my plugin directory my-first-block is my block name. Now we need to put the title, description, icon, and category, Here myCustomBlock is my namespace of plugin.
The edit
function is use for editor.
The save
function is for frontend and define how the attributes will combine and render a final markup.
Lets bundle it
Create css and js file in myFirst-block/src for styles and scripts.
//src/editor.css .wp-block-myCustomBlock-my-first-block { color: cornflowerblue; }
//src/style.css .wp-block-myCustomBlock-my-first-block { color: tomato; }
Our block will shown in gutenberg modules


Create advance block for card component
We are going to use useBlockProps
React hook on the block wrapper element, useInnerBlocksProps for adding default components of gutenbrg into our custom block like heading, paragraph, buttons etc and MediaUpload for card Image.
Here we will use useInnerBlocksProps for giving support of adding other Blocks inside our custom Block ex: Button, Text, Heading, etc.
// src/index.js import { registerBlockType } from '@wordpress/blocks'; import { useBlockProps, RichText, MediaUpload, InnerBlocks } from '@wordpress/block-editor'; registerBlockType('gutenreact/webkul-cards', { title: 'Webkul Card Section', icon: 'columns', category: 'widgets', attributes: { content: { type: 'string', source: 'html', selector: 'p', }, description: { type: 'string', source: 'html', selector: 'p', }, imgUrl: { type: 'string', }, }, edit: (props) => { const { attributes: { content, description, imgUrl }, setAttributes, } = props; const blockProps = useBlockProps(); const onChangeContent = (newContent) => { setAttributes({ content: newContent }); }; const onChangeDescription = (newDescription) => { setAttributes({ description: newDescription }); }; const onImageSelect = (newImgUrl) => { setAttributes({ imgUrl: newImgUrl.sizes.full.url }); }; const ALLOWED_BLOCKS = [ 'core/buttons' ]; return ( <div className='webkul-card'> <MediaUpload onSelect={onImageSelect} render={ ({ open }) => { return imgUrl ? <img onClick={open} src={imgUrl} /> : <button onClick={open}> Upload Image </button> } } title="Insert Image" /> <RichText {...blockProps} tagName='h3' onChange={onChangeContent} placeholder='title' value={content} /> <RichText {...blockProps} tagName='p' onChange={onChangeDescription} placeholder='Short description' value={description} /> <InnerBlocks allowedBlocks={ ALLOWED_BLOCKS } /> </div> ) }, save: (props) => { const blockProps = useBlockProps.save(); return ( <div className='webkul-card'> <img src={props.attributes.imgUrl} /> <RichText.Content {...blockProps} tagName='h3' value={props.attributes.content} /> <RichText.Content {...blockProps} tagName='p' value={props.attributes.description} /> <InnerBlocks.Content /> </div> ) } });
We can also have a validator function ALLOWED_BLOCKS in which we can allow only selected innerBlocks to add in our custom Block
const ALLOWED_BLOCKS = [ 'core/image', 'core/paragraph' ]; //... <InnerBlocks allowedBlocks={ ALLOWED_BLOCKS } />;
Here we give support of Image and Paragraph to our custom Block, you can give more Blocks. you can check core blocks here.
Lets bundle it
npm run start
Now our card block is appear in gutenberg editor
Now we write some css for frontend and editor
// src/editor.css .webkul-card { text-align: center; background: #d5d5d5; padding: 40px 20px; border: 1px solid #000000; }
// src/style.css .webkul-card { text-align: center; background: #d5d5d5; padding: 40px 20px; }

If you need custom WordPress Development services then feel free to reach us and also explore our exclusive range of WordPress WooCommerce Extensions.
!!Have a Great Day Ahead!!
Be the first to comment.