Writing my first Gutenberg Block

Inspired by a comment I read a week or so ago, I wrote my first Gutenblock. Here are my impressions of that process.

I initially planned on copying an existing block, but quickly found the example in the blocks directory README.

This is the ultimate result, you should open the example and the result to follow along how things changed.

Getting from one to the other was not too tricky, but did have a handful of surprises and confusing bits.

I started with changing the block name, which caused the first problem – I got an error that it needed to be namespaced. That was easily rectified.

Changing the title was easy enough, but I didn’t know what I should change the category to. I got an error when I left it blank, so I set it to common.

Next up, changing the attribute definition. Changing the type to ‘int’ was a lucky guess, there was nothing to suggest what the valid types are. source confused me for some time, as I didn’t really know what it needed to be. I figured I needed to store the value as a data attribute on the HTML that Star returned, so I wrote a basic version of the Star element, and tried to save it there. It… didn’t work. I tried several variations of this before noticing in the docs that source is optional. So, I tried deleting it, and it worked! That bit of magic made me smile, but I was a bit annoyed I spent so much time on a non-problem.

Writing the setStars() method was easy enough, even without really knowing what the props.setAttributes() call did.

Trying to add the Stars render to the children array gave me a weird error, complaining that the element needed an identifier. I tried adding an id attribute to the HTML that Stars rendered, but that didn’t help. Googling the error message showed me that I needed to set the key attribute, which was kind of weird, and I didn’t understand why it was necessary now, when the example didn’t need it. But it worked, so I moved on.

Adding the input element to children was also easy. I got the same error as before about needing an identifier, so I added a key attribute to that, too. I added all the extra attributes for fun, but realised when defining the min / max attributes that there was no nice way to validate the data being put into the stars attribute.

It was around this time that I discovered the Stars element wasn’t actually rendering, the problem was that I didn’t know how to put the text inside the div element. Did I need to append it? Was there a createTextNode() method I needed to call? As it turns out, it just magically accepted the string, but I only found that out by guessing. (Excuse the hacky math to add the “½”, I got a little carried away.)

One annoyance throughout was that every time I changed the attribute definition, or the output of Stars, Gutenberg threw a warning about the format changing. It seems like this warning would show whenever a plugin upgrade included a block change, though I didn’t test that.

And that’s about the sum of it – I found it to be a generally pleasant experience, it was nice that I could do this all without needing to compile from JSX, but I knew that option was there for if I wanted it. It’s still a bit of a raw experience, but it shows a lot of promise for creating a delightful development experience.