Gutenberg Tips — Generate your block’s class name using useBlockProps()

Franky Hung
3 min readMay 8, 2021

useBlockProps has been introduced since WordPress 5.6, which fixes a previous weird issue where the className property is only passed in the edit function but not the save function in registerBlockType. With useBlockProps, we can use the same ‘wp-block-’ prefixed class name in both the edit and save functions!

Assuming your registered block type has the name: ‘myfirstblock/gtg-demo’, then the default generated className we can extract from useBlockProps would be ‘wp-block-myfirstblock-gtg-demo’(forward slashes are converted to hyphens).

Prerequisites of using useBlockProps

Firstly, make sure your WordPress version is 5.6 or above.

Secondly, pass key/value pair (‘api_version’ => 2) to the register_block_type arguments array like this:

register_block_type( 'myfirstblock/gtg-demo', array(
'api_version' => 2,
'editor_script' => 'gtg-demo-editor-script',
'editor_style' => 'gtg-demo-editor-style',
'style' => 'gtg-demo-style'
) );

Thirdly, import useBlockTypes from wp.blockEditor at the top of your editor script:

const { useBlockProps } = wp.blockEditor;

Lastly, set apiVersion as 2 also in registerBlockType in your editor script:

registerBlockType( 'myfirstblock/gtg-demo', {
apiVersion: 2,
...

Usage of useBlockProps

The Official block tutorial has also been updated to demonstrate with this React hook. The most verbose explanation I can find on WordPress docs on how to use useBlockProps is at here. Quoting from the docs:

…but in order for the Gutenberg editor to know how to manipulate the block, add any extra classNames that are needed for the block… the block wrapper element should apply props retrieved from the useBlockProps react hook call. The block wrapper element should be a native DOM element, like <div> and <table>, or a React component that forwards any additional props to native DOM elements. Using a <Fragment> or <ServerSideRender> component, for instance, would be invalid.

If the element wrapper needs any extra custom HTML attributes, these need to be passed as an argument to the useBlockProps hook.

See the below code example which shows how the React hook can be used; I’m importing the hook from the global wp variable:

const { registerBlockType } = wp.blocks;
const { useBlockProps } = wp.blockEditor;
import './editor.scss';
registerBlockType( 'myfirstblock/gtg-demo', {
apiVersion: 2,
title: 'GTG Demo Block',
icon: 'heading', // https://developer.wordpress.org/resource/dashicons/#heading
category: 'text',
edit: props => {
const blockProps = useBlockProps( {
className: 'gtg-demo-h1',
'data-id': 'special-h1-id'
} );
return (
<h1 {...blockProps}>Hello World!</h1>
);
},
save: props => {
const blockProps = useBlockProps.save( {
className: 'gtg-demo-h1',
} );
return (
<h1 {...blockProps}>Hello World!</h1>
);
},
} );

My rendered h1 element in the Block Editor

Notice that we have both the generated ‘wp-block-myfirstblock-gtg-demo’ and the custom ‘gtg-demo-h1’ class names. Also our custom ‘data-id’ attribute is included too:

<h1 class="wp-block-myfirstblock-gtg-demo block-editor-block-list__block wp-block is-selected gtg-demo-h1" data-id="special-h1-id" id="block-f0ac2755-01e3-4e3b-9356-4af9ee46fb0d" tabindex="0" role="group" aria-label="Block: GTG Demo Block" data-block="f0ac2755-01e3-4e3b-9356-4af9ee46fb0d" data-type="myfirstblock/gtg-demo" data-title="GTG Demo Block">Hello World!</h1>

My rendered h1 element in the frontend

<h1 class="wp-block-myfirstblock-gtg-demo gtg-demo-h1">Hello World!</h1>

--

--

Franky Hung

Founder of Arkon Digital. I’m not a code fanatic, but I’m always amazed by what code can do. The endless possibilities in coding is what fascinates me everyday.