Editable Gutenberg Block
In this tutorial we are going to continue to work with the “subscription form” block we created in the previous tutorial.
It was completely static if you remember, but for now we are going to make it editable just like that:

Setting up the Attributes
Each field you want to make editable should have its own attribute, you can think of it like of a meta key and meta value of a block. Today we are configuring the attributes of blocks in block.json file. In the old times we were doing it primarily in registerBlockType()
function and this way is still working but I highly recommend to use block.json
instead.
"attributes": {
"heading": {
"type": "string",
"source": "html",
"selector": "h3",
"default": "Like this post? Join my mailing list!"
},
"buttonText": {
"type": "string",
"source": "text",
"selector": "span",
"default": "Subscribe"
}
}
I think it would be great to highlight a couple moment in JSON code above.
- As you can see we have two attributes here –
heading
andbuttonText
(you can choose the names), it is just because we have two editable elements in our block (check the screenshot above). - For out simple block the attribute properties
type
,source
,selector
anddefault
should be quite clear to understand. You can read more about them in Gutenberg official documentation.
RichText Component
edit()
Now we have to replace all the static HTML tags from the original edit() function with <RichText>
component. So we are going to replace <h3>
and <span>
tags.
import { useBlockProps, RichText } from '@wordpress/block-editor';
export default function Edit( { attributes, setAttributes } ) {
const blockProps = useBlockProps();
return(
<div {...blockProps}>
<RichText
tagName="h3"
value={ attributes.heading }
allowedFormats={ [ 'core/bold', 'core/italic' ] }
onChange={ ( heading ) => setAttributes( { heading } ) }
placeholder="Enter heading here..."
/>
<p>
<span>Email address</span>
<RichText
tagName="span"
value={ attributes.buttonText }
allowedFormats={ [] }
onChange={ ( buttonText ) => setAttributes( { buttonText } ) }
placeholder="Button text..."
/>
</p>
</div>
)
}
Ok, let’s look at RichText
component parameters I used. tagName
and placeholder
should be clear for you, but what about the other ones?
value
– here we are going to provide the attribute value, if it doesn’t exist, the default value will be used which has been provided inblock.json
before.allowedFormats
– it allows you to define which formatting buttons are you going to use for this specificRichText
component, accepts valuescore/bold
,core/italic
,core/link
,core/strikethrough
,core/code
,core/image
,core/underline
,core/text-color
,core/subscript
,core/superscript
,core/keyboard
, by default all of them are available. If you want to deactivate everything, just pass an empty array[]
.onChange
– this parameter accepts a function name or an arrow function which you can see in my example. This function changes the component attribute on the fly which is its value in this case.
save()
Nothing especial here, we’re just using RichText.Content
to display the content of our RichText component.
import { useBlockProps, RichText } from '@wordpress/block-editor';
export default function Save( { attributes } ) {
return (
<div {...useBlockProps.save()}>
<RichText.Content tagName="h3" value={ attributes.heading } />
<form>
<input type="email" placeholder="Enter your email address" />
<RichText.Content tagName="button" value={ attributes.buttonText } />
</form>
</div>
);
}

Misha Rudrastyh
Hey guys and welcome to my website. For more than 10 years I've been doing my best to share with you some superb WordPress guides and tips for free.
Need some developer help? Contact me