Skip To Main Content

React Components to Gutenberg Blocks

The @faustwp/block-editor-utils package provides helper functions for converting existing React components into Gutenberg blocks. This is very useful for when you already have some components and you want to test them in Gutenberg without needing to write any code to port them. You will also be able to re-use the same React component in both places; the Headless side and the Editor side.

Make sure you have completed the initial setup for Faust at Getting Started and the Get started with Gutenberg Blocks Provider and Viewer.

Quick Start

The @faust/cli package includes a helpful command to detect, compile and upload your custom blocks into WordPress all within the Headless project!

In this guide we provide the steps required to create a new block using this workflow. We are creating a new block named my-first-block.

First, from your root folder, install the required dependencies:

$ npm install @wordpress/scripts @faustwp/block-editor-utils --save-dev

You should see the following file and folder structure now:

tree -L 2 .
.
├── README.md
├── faust.config.js
├── globalStylesheet.css
├── next.config.js
├── package.json
├── pages
│   ├── [...wordpressNode].js
│   ├── _app.js
│   ├── api
│   ├── index.js
│   └── preview.js
├── possibleTypes.json
├── styles
│   └── blocks.scss
├── wp-blocks
│   └── index.js
└── wp-templates
    ├── front-page.js
    └── index.jsCode language: CSS (css)

Now we’re ready to explore the process of using this package’s helpers to convert a React component to blocks.

Porting A Simple Component

For the purposes of this tutorial we are using the a simple React component. Add this code inside the wp-blocks/my-first-block folder:

// MyFirstBlock.jsx
function MyFirstBlock({ style, className, attributes, children, ...props }) {
    const styles = {
      ...style,
    };
    const cssClassName = 'create-block-my-first-block';
    return (
        <div
            style={styles}
            className={cssClassName}
            dangerouslySetInnerHTML={{ __html: attributes.message }}
        />
    );
}

export default MyFirstBlock
Code language: JavaScript (javascript)

This pure React component consists of div element with three attributes that controls the content and the style of the box. Let’s describe them briefly:

  • message: is a text message that gets displayed.
  • bg_color: controls the background color.
  • text_color: controls the text color.

We would like to use this React component in WordPress using the Block editor. Traditionally, this step would require us (the developers) to register a block within WordPress, provide a block.json and write code for the Edit and Save functions for the editor. Once those steps are done, then the block would be usable in the block editor list.

That is a lot of know-how and development effort for simply trying to use the React component in the editor side. What if we just provided the React component and let the framework handle all the block registration and creating the editor form fields for changing the content?

This is what @faustwp/block-editor-utils package tries to do. It provides a registerFaustBlock helper function, that handles all the necessary configuration, registration and generation of Editor Form fields and Inspector controls for you. From the perspective of the Headless Developer, they provide the React component and are able to review this within the WordPress block editor and re-use it in both places.

Within your wp-blocks/my-first-block folder replace the index.js contents with the following code:

// index.js
import './style.scss';
// import block.json
import metadata from './block.json';

// import our React component
import MyFirstBlock from './MyFirstBlock';

import { registerFaustBlock } from '@faustwp/block-editor-utils';

// Register the React component in Gutenberg
registerFaustBlock(MyFirstBlock, {blockJson: metadata})
Code language: JavaScript (javascript)

The registerFaustBlock  helper takes the following arguments:

  • component: the actual React component to convert into a Gutenberg block. (Required).
  • metadata: a metadata object that contains several fields:
    • blockJson: the block.json object that describes the component attributes. (Required).
    • edit: provides a custom Edit function that describes the structure of your block in the context of the editor. (Optional).
    • save: provides a custom Save function that defines the way in which the different attributes should be combined into the final markup. (Optional).

Now let’s take a look at the block.json. Since we declared three configurable attributes for our component, we need to declare them as attributes here.

Here is the final block.json with the assigned attributes object:

{
	"$schema": "https://schemas.wp.org/trunk/block.json",
	"apiVersion": 2,
	"name": "create-block/my-first-block",
	"version": "0.1.0",
	"title": "My First Block",
	"category": "widgets",
	"icon": "smiley",
	"description": "Example block scaffolded with Create Block tool.",
	"supports": {
		"html": false
	},
    "attributes": {
        "message": {
            "type": "string",
            "default": "My First Block"
        },
        "bg_color": { "type": "string", "default": "#000000" },
        "text_color": { "type": "string", "default": "#ffffff" }
    },
	"textdomain": "my-first-block",
	"editorScript": "file:./index.js",
	"editorStyle": "file:./index.css",
	"style": "file:./style-index.css"
}
Code language: JSON / JSON with Comments (json)

Syncing the block with WordPress

Add the following command in your package.json scripts and run it afterwards:

 "scripts": {
    ...
    "blockset": "faust blockset"
  },Code language: JavaScript (javascript)
$ npm run blockset

If everything goes OK the cli tool will compile the blocks within the wp-blocks folder and upload them to your WordPress site in a special location that Faust uses to detect and register the blocks.

Trying out the Component in the Block Editor

We can now try to use the component straight in the editor side. This is what it will look like at first glance in Edit mode:

React Component in Edit Mode

You can interact with the form fields, and then click outside the block contents where you will see the component rendered in Preview mode.

React Component in Preview Mode.

Configuring the Form Controls

So far we’ve been able to render the React component in the Block Editor, change some of the attributes, and reflect the changes in the page.

However, a few of the attributes that control the color are using text field controls, which may prove problematic since they allow invalid values. What if we wanted to use a proper color picker component?

Since the block.json attribute types do not allow color as a value, we will have to provide a different configuration to allow that option.

When registering the React component using registerFaustBlock , it allows extra configuration to be used in case you want to declare which kinds of controls to use on each attribute.

Add the following config object as a property to the MyFirstBlock function:

// MyFirstBlock.jsx
...
MyFirstBlock.config = {
	name: "MyFirstBlock",
	editorFields: {
		bg_color: {
			location: "inspector",
			control: "color",
		},
		text_color: {
			location: "inspector",
			control: "color",
		},
	},
};
Code language: JavaScript (javascript)

Here we included an object with the following properties:

  • name: the name of the block.
  • editorFields: the list of Editor metadata configuration. This consists of two attributes that we want to specify: the type of control to use and the location within the editor. For example, by using location: "inspector", we are telling this control to appear in the Block Sidebar section. By using control: "color", we are indicating that we want to use a ColorPicker component instead of the regular TextControl.

Once you update the component, you can refresh the page and create a new block. Now instead of having two text fields inside the block, we have two ColorPicker fields in the sidebar section:

Using ColorPicker controls for the color attributes.

Form Control Reference List

So far we’ve seen examples of two controls: The ColorPicker handled by the control: "color" and the TextControl, which is set as default for every type: "string" in the block.json attributes list.

The corresponding table represents the mapping logic between the block.json attributes and their associated fields:

typefieldcomment
stringTextControlRenders a TextControl field of type text
booleanRadioControlRenders a RadioControl field
integerTextControlRenders a TextControl field of type number
numberTextControlRenders a TextControl field of type number
objectTextAreaControlRenders a TextAreaControl field
Table of block.json attributes types to Editor Controls

The following control types will also be available when using the editorFields metadata when specifying a control property:

controlfieldcomment
colorColorPickerRenders a ColorPicker field
textTextControlRenders a TextControl field of type text
textareaTextAreaControlRenders a TextAreaControl field
radioRadioControlRenders a RadioControl field
selectSelectControlRenders a SelectControl field
rangeRangeControlRenders a RangeControl field
numberTextControlRenders a TextControl field of type number
checkboxCheckBoxControlRenders a CheckBoxControl field

NOTE:
The editorFields configuration provides necessary hints for the helper to render the specified controls. It always overrides any configuration that is declared in the block.json attributes section. If you are not seeing the appropriate control used, check that your editorFields contain the correct attribute name and the correct control property.

Reference

The following RFC document explains in detail the different options and configurations regarding the usage of the @faustwp/block-editor-utils.