Using Block Attributes to Enable User Editing

Giving users the ability to edit block elements is an important part of block development. In this tutorial, you will learn all about block attributes, and how you can use them to create blocks that your users can edit.

Learning outcomes

  1. Learn to define block attributes
  2. Pass attributes to your block code via blockProps
  3. Access block attributes in your code
  4. Make attributes editable via the Settings Sidebar

Comprehension questions

  1. How do you define attributes for a block?
  2. What is the process called where you extract the block properties in the edit component or save function?
  3. Which Block editor component allows users to edit text?


Hey there, and welcome to Learn WordPress.

In this tutorial, you will learn all about block attributes, and how you can use them to create blocks that your users can edit. This tutorial builds on the lessons learned from the Turning a shortcode into a block tutorial. If you’ve not watched that video, I recommend doing so before watching this one.

In this tutorial, you will learn: How to define block attributes in your block.json file, how attributes are passed to your block through block props, how to access the attributes in your block, and how to add fields to the Block Editor sidebar so users can edit the block attributes.

Let’s say you have a subscribe block that needs to be updated to support attributes. The current block generates HTML content only, a header element with a heading subscribe, and a paragraph that contains some text and a link to a URL on the site. You want to be able to allow the user to update the heading text of the block when it’s added in the editor. To do this, you first need to add some attributes to the block.

To enable block attributes you add them in the block.json file. You can read more about attributes in the WordPress documentation on the Block Editor, in the Reference Guides, Block API Reference, Attributes. To start let’s add an attribute to manage the heading text.

We’ll add attributes, heading, give it a type and a default.

You can add the attributes as a top level field anywhere in your block.json file. There are other keys available to each attribute which control various elements of the attribute. But at a minimum, each attribute definition must contain either a type or an enum. You can add the default key with a value so that the block renders with some content in the editor. Now that that attribute has been defined, you can access it in your edit component and save function through something called a React prop.

Like most programming languages, React components and functions can accept arguments. In the case of the block’s edit component or save function, the block properties or props are passed as a single argument. Therefore, you can define a parameter in your edit component to save function to accept these props. Let’s create this object in our edit component for the purposes of this tutorial. Let’s call it blockProps. And then we’ll log it to the browser console to see what happens.


And then just in case, we’ll make sure that our build is running:

npm start

And switch over to the browser.

If you add the block to a post, turn on developer tools in the browser and view the output of the console, you can see the blockProps object.

So we’ll search for subscribe and then do the console. And there we can see the most recent object. There it is.

Notice that the block props object contains the attributes property, which is passed from the block json file when the block is rendered. While you’re looking at this object, notice that it also has a function property called setAttributes, which we’ll use later.

You can use something called JavaScript destructuring assignment syntax to extract specific object properties in your edit or save function. For example, we just need the attributes from the block props. So we can extract them from the object like this.

So it’s curly braces, and then attributes and just take this out for sure.

The first step is to update the Edit component to use the heading value from the attributes property.

So in that case, we will replace subscribe with attributes and we called it heading.

Let’s also update the heading attributes default value so we can see it in the block in the editor and on the front end. So let’s make this subscribe now. So we see that change. And there’s attributes heading there. And then let’s check in the browser. So remove, update, refresh those developer tools for now. And then add, subscribe, and there’s the change subscribe now.

Now you’re going to want to allow your users to edit the attribute value when they add the block to a post. You can do this using the setting sidebar by implementing the InspectorControls component and using the TextControl component.

The WordPress Block Editor handbook has a detailed page on how to implement block settings in both the Toolbar and the Sidebar. It also contains example code using the various control components for the sidebar that you can try out in your own projects. Explaining in detail how to implement these settings is outside the scope of this tutorial. For now, let me show you what the code would look like for this block.

Just inside here looks like this. So it’s InspectorControls. And then inside InspectorControls, there is a TextControl component. InspectorControls keys set to setting takes control has a class name, a label of hitting a value of attributes heading and then the unchanged method.

The InspectorControls components allows you to add inputs to the Setting Sidebar for the user to edit block attributes. The important thing to focus on is the TextControl element. If you look at the TextControl for the client attributes, it has a label attribute which in this case outputs the string “heading”. The component’s value is set to the value of attributes.heading. The onChange event calls a function called setAttributes, which will update the value of the attributes.headding field to whatever is entered in the text field.

Remember the setAttributes function we saw earlier in the block props? This function allows you to store the user’s input for a specific attributes, so it can be passed to the save component, you will need to include the setAttributes function as an argument in your edit component for it to be available to the component. You can also extract that function property in the same way that you did for attributes.

So here we can add a comma and then include setAttributes.

Lastly, you’ll also need to update this component to import the InspectorControls and TextControl components being used in the sidebar. InspectorControls is available in the WordPress Block Editor package, so you can import it like this.

So if we scroll up, the block props, useBlockProps is being imported from the block-editor. So we can also import Inspector Controls. TextControl is available in the @wordpress/components package. So you can import it like this.

So if we say import TextControl from @wordpress/components.

These packages are available to your code from WordPress core.

Let’s look at what this looks like an editor.

Update and refresh.

Now if you edit your block and look over at the settings, you can adjust the header text. As you type the Block Editor is updated. However, if you save in preview this saved version will not have the changes. This is because you need to update the save function to use the attribute value passed from the component.

So if we go back to our code, open up save.

We can destruct the props in the same way and then use the attribute value.

Okay, notice how you don’t specify the setAttributes function here as you’re not going to be updating attributes in the Save component. In fact, if you inspect the props passed to the save function, the setAttributes function isn’t even available to the save function.

If you refresh, edit, and save your block, you should now see the new value on the front end.

So let’s refresh. Let’s first update make a change, update that, lets view that on the frontend, Subscribe Here Today.

At the same time, if you switch the Block Editor to code, to the Code editor view, you can see how the attribute is saved in the block element code.

So if we click there and say code editor, we can see that in the learn-subscribe-block, the heading is stored with the block.

At this point, you probably agree that the controls don’t look great, especially if we compare them to other sidebar controls.

So there’s a bit of padding and spacing.

To fix this, we can use the PanelComponents in our InspectorControls component.

First, go back to your edit component and import the PanelBody and PanelComponents from @wordpress/components.

So here we will say, I’m going to put these in beginning, Panel and Panel, next update your InspectorControls component and wrap the TextControl component in a Panel and PanelBody. So we want to wrap the TextControl component so let’s create some space and then we can go Panel, pop this at the end and then PanelBody, pop it at the end and then just use two attributes. And then just clean up.

Notice how I’m using the title and initialOpen attributes of the PanelBody component. If we look back in the editor, so let’s refresh this and let’s add the block back.

Now we can see the attributes fields in the sidebar look much better.

Congratulations, you’ve successfully added an attribute to your subscribe block. You can learn more about attributes the Setting Sidebar, and TextControl and Panel components by searching for them in the Block Editor handbook.

So for example, if I want to learn about panel, I can hit enter and view the details of the panel component.

Happy coding

Workshop Details


Jonathan Bossenger

WordPress Developer Educator at Automattic, full-time sponsored member of the training team creating educational content for developers on Learn WordPress. Husband and father of two energetic boys.