As WordPress continues to evolve, the Gutenberg editor has become an integral part of the content creation experience. For developers, this shift presents an exciting opportunity to extend WordPress’s functionality through custom blocks. By leveraging React, we can create powerful, interactive blocks that enhance the editing experience and unlock new possibilities for content creators.
In this guide, we’ll walk through the process of creating custom Gutenberg blocks using React, from setting up your development environment to publishing your block for use in WordPress sites.
1. Understanding Gutenberg and React
Before we dive into development, let’s briefly recap why Gutenberg uses React and what this means for block development:
- Gutenberg is built with React, a popular JavaScript library for building user interfaces.
- Custom blocks are essentially React components with additional WordPress-specific functionality.
- Understanding React concepts like components, state, and props is crucial for effective block development.
2. Setting Up Your Development Environment
To get started with custom block development, you’ll need to set up your environment:
a) Install Node.js and npm
Ensure you have Node.js and npm (Node Package Manager) installed on your system. You can download them from the official Node.js website.
b) Install the @wordpress/scripts package
This package provides a set of scripts for WordPress development. Install it globally:
npm install -g @wordpress/scripts
c) Create a new plugin directory
In your WordPress installation’s wp-content/plugins
directory, create a new folder for your custom block plugin.
d) Initialize your project
Navigate to your plugin directory in the terminal and run:
npm init
npm install @wordpress/scripts --save-dev
3. Creating the Basic Block Structure
Let’s create a simple custom block to get started:
a) Create the main plugin file
In your plugin directory, create a file named my-custom-block.php
:
<?php
/**
* Plugin Name: My Custom Block
* Description: A custom Gutenberg block created with React
* Version: 1.0.0
* Author: Your Name
*/
function my_custom_block_init() {
register_block_type( __DIR__ );
}
add_action( 'init', 'my_custom_block_init' );
b) Create the block files
Create a src
directory in your plugin folder with two files:
index.js
:
import { registerBlockType } from '@wordpress/blocks';
import { useBlockProps } from '@wordpress/block-editor';
registerBlockType( 'my-plugin/my-custom-block', {
title: 'My Custom Block',
icon: 'smiley',
category: 'common',
edit: function() {
const blockProps = useBlockProps();
return (
<div { ...blockProps }>Hello from the editor!</div>
);
},
save: function() {
const blockProps = useBlockProps.save();
return (
<div { ...blockProps }>Hello from the frontend!</div>
);
},
} );
style.css
:
.wp-block-my-plugin-my-custom-block {
background-color: #f0f0f0;
padding: 20px;
border: 1px solid #ddd;
}
c) Configure your block
Create a block.json
file in your plugin’s root directory:
{
"apiVersion": 2,
"name": "my-plugin/my-custom-block",
"title": "My Custom Block",
"category": "common",
"icon": "smiley",
"description": "A custom block created with React",
"textdomain": "my-plugin",
"editorScript": "file:./build/index.js",
"editorStyle": "file:./build/index.css",
"style": "file:./build/style-index.css"
}
4. Building and Testing Your Block
Now that we have our basic structure, let’s build and test the block:
a) Add build scripts
In your package.json
file, add these scripts:
"scripts": {
"build": "wp-scripts build",
"start": "wp-scripts start"
}
b) Build your block
Run the build command to compile your block:
npm run build
c) Test your block
Activate your plugin in WordPress and try adding your custom block in the Gutenberg editor.
5. Enhancing Your Block with React Components
Let’s make our block more interactive by adding some React components:
import { registerBlockType } from '@wordpress/blocks';
import { useBlockProps, RichText } from '@wordpress/block-editor';
import { useState } from '@wordpress/element';
registerBlockType('my-plugin/my-custom-block', {
title: 'My Custom Block',
icon: 'smiley',
category: 'common',
attributes: {
content: {
type: 'string',
source: 'html',
selector: 'p',
},
},
edit: function(props) {
const { attributes, setAttributes } = props;
const blockProps = useBlockProps();
const [count, setCount] = useState(0);
return (
<div { ...blockProps }>
<RichText
tagName="p"
value={ attributes.content }
onChange={ (content) => setAttributes({ content }) }
placeholder="Enter your text here..."
/>
<button onClick={() => setCount(count + 1)}>
Clicked {count} times
</button>
</div>
);
},
save: function(props) {
const blockProps = useBlockProps.save();
return (
<div { ...blockProps }>
<RichText.Content tagName="p" value={ props.attributes.content } />
</div>
);
},
});
This enhanced block now includes editable text content and a clickable button that demonstrates React state management.
6. Adding Block Controls
Gutenberg provides various components for adding controls to your block. Let’s add some:
import { registerBlockType } from '@wordpress/blocks';
import { useBlockProps, RichText, InspectorControls } from '@wordpress/block-editor';
import { PanelBody, ColorPicker } from '@wordpress/components';
registerBlockType('my-plugin/my-custom-block', {
// ... previous block configuration ...
attributes: {
content: {
type: 'string',
source: 'html',
selector: 'p',
},
backgroundColor: {
type: 'string',
default: '#ffffff',
},
},
edit: function(props) {
const { attributes, setAttributes } = props;
const blockProps = useBlockProps({
style: { backgroundColor: attributes.backgroundColor },
});
return (
<>
<InspectorControls>
<PanelBody title="Block Settings">
<ColorPicker
color={ attributes.backgroundColor }
onChangeComplete={ (color) => setAttributes({ backgroundColor: color.hex }) }
/>
</PanelBody>
</InspectorControls>
<div { ...blockProps }>
<RichText
tagName="p"
value={ attributes.content }
onChange={ (content) => setAttributes({ content }) }
placeholder="Enter your text here..."
/>
</div>
</>
);
},
save: function(props) {
const blockProps = useBlockProps.save({
style: { backgroundColor: props.attributes.backgroundColor },
});
return (
<div { ...blockProps }>
<RichText.Content tagName="p" value={ props.attributes.content } />
</div>
);
},
});
This version adds a color picker in the block’s settings panel, allowing users to change the block’s background color.
7. Handling Block Styles
To make your block visually appealing and consistent with WordPress styles, consider these tips:
- Use WordPress components and existing styles where possible to maintain consistency.
- Create editor-specific styles to ensure your block looks good while editing.
- Use CSS modules or CSS-in-JS solutions to scope your styles and avoid conflicts.
8. Testing and Debugging
Thorough testing is crucial for block development:
- Use the WordPress Block Editor Validator to check your block for errors.
- Test your block in different themes and with other plugins to ensure compatibility.
- Use browser developer tools to debug React components and track state changes.
9. Publishing Your Block
Once your block is ready, you can publish it:
- Package your block as a WordPress plugin.
- Submit it to the WordPress plugin repository or distribute it through your own channels.
- Provide clear documentation on how to use and customize your block.
Conclusion
Creating custom Gutenberg blocks with React opens up a world of possibilities for extending WordPress functionality. By following this guide, you’ve learned the basics of block development, from setting up your environment to creating interactive, customizable blocks.
Remember, the key to successful block development is understanding both React principles and WordPress-specific APIs. As you continue to develop blocks, explore the WordPress Block Editor Handbook and stay updated with the latest Gutenberg developments.
With practice and experimentation, you’ll be able to create sophisticated, user-friendly blocks that enhance the WordPress editing experience and bring new capabilities to content creators. Happy coding!