Taking the Leap: Building My First WordPress Block Plugin

Like most years, I spent this U.S. Independence Day cooped up with my furry friends. I closed all the windows, shuttered the blinds, switched on a couple of fans for white noise, and clicked the television on. My cats and I relaxed. It is my job to keep them calm while my — usually drunken — compatriots burn hundreds of dollars away in the night sky. It is my ritual, and I enjoy it.

For this holiday, we re-watched Season 1 of Star Trek: Lower Decks, and I learned how to build a block plugin.

This was not my first attempt. When the block editor launched nearly three years ago, I tinkered with a few block type ideas. However, I never got far. Documentation was sparse, and I had almost no experience with JavaScript beyond building trivial bells and whistles for front-end design.

Leaving my day job as a developer to write for WP Tavern also meant limited time to learn block development. And, my free time for the last couple of years has been filled with other projects. Lately, I have had the urge to jump back in and start building things for fun once again. My extended sabbatical from development work gave me time to pursue other interests while allowing my well of creativeness a chance to refill. The break did me some good.

With time to kill yesterday afternoon, I dove right in. After a couple of hours of reading docs, studying other developers’ code, and breaking things, I had a functional block for a breadcrumbs list.

WordPress block inserter with a breadcrumbs block selected, showing its preview.
Custom block registered and ready to insert.

Marcus Kazmierczak’s Copyright Block plugin helped me get over one of the initial humps. It was helpful to see real-world, non-example code written in vanilla JavaScript to get to the meat of how the system worked.

My overall thoughts on building custom block types?

It was easier than I thought it would be. Documentation is, at the same time, both overwhelming and limiting. It is tough to find the correct answer if you do not even know what you are looking for. The barrier to entry is much higher than when I built my first plugin in 2007. The Block Type API makes some things stupidly simple but complicates others.

Successfully inserting my first block type into the editor canvas was gratifying. I don’t think that feeling ever goes away as a developer.

Breadcrumbs list block shown in the WordPress post editor.
Successful insertion and rendering of my first block plugin.

I am excited about the potential for blocks, such as a breadcrumbs list, when the site editor launches. Many similar features do not make sense in the post editor. However, when users can make direct edits to their templates, it will open a world of possibilities.

Learning Curve

I know enough JavaScript to be a danger to myself and others. Having spent almost the entirety of my professional career in the WordPress realm has meant focusing on PHP. But, programming is programming. Once you have a strong understanding of one language, it not an impossible leap to piddle around enough to create a functional script in another. Most of the same foundational concepts are there. The hurdle is often with learning some new syntax.

However, the biggest obstacle with “modern” JavaScript is setting up the build tools, bundlers, and more. It can be a tall order to even type out that first line of code.

Sure, some of the documentation has vanilla JavaScript examples, but when you get into anything more complex than the basics, it is not so vanilla anymore. You will need a way to bundle JavaScript and transform JSX syntax. That means tools like webpack and Babel.

WordPress has its own script for cutting through most of the complexity, but I recommend Laravel Mix. It is simple enough for even the least-savvy JavaScript programmers among us and has thorough documentation. It is a script made for folks who want to worry less about tooling and more about actually writing code.

Block building is also a different kind of leap. Whether it was custom template tags, shortcodes, widgets, or hooks, traditional WordPress development has meant building those in a PHP environment. I suspect that most plugin developers have tons of features that they can bring to the masses via the block editor. They will often rely on server-side rendering. WordPress has a ServerSideRender component for actually handling this.

One of the handiest features of registering block types is the block “supports” system. Want a background color option? Just one line of code will do. Want the user to access the font-size control? That is a single line too. With little effort, I extended my breadcrumbs block to include a ton of styling options for users. And, they adapt to the site’s active theme.

Multiple breadcrumb trail blocks with different styles applied to them in the WordPress post editor.
Testing various combination of block-supported styling options.

The list of block-supported features offers an array of standardized options at pretty much no development cost. Even the Customize API, previously the most advanced tool for building form fields, did not come this close.

Building custom inspector controls was straightforward once I got the hang of how the block edit piece of the puzzle worked. For now, I have a simple toggle option for enabling/disabling a feature. Often, the hardest part is just finding what you are looking for. WordPress has a massive library of components to choose from.

At this point, I have a basic block on the client (editor) side. Most of the complexity is handled on the server via PHP. If I could build this in an afternoon while attending to nervous cats, it should not be a stretch for more plugin authors to hop aboard this train. There are thousands of shortcodes and widgets that developers can convert to blocks with minimal code.

I am not ready to release my breadcrumbs block into the wild just yet. There is still some fine-tuning left to do and a few advanced features to implement. Also, a breadcrumbs list is primarily needed in a site editor context where users can drop it into something like their header template. We are not there yet, but I will undoubtedly share the final result with the community when we are.

Next, I will try to build a block that does not rely on server-side rendering. I think I have the hang of it now. Breaking through that initial barrier is always the hardest step.

13

13 responses to “Taking the Leap: Building My First WordPress Block Plugin”

  1. Thanks Justin, great article.
    I also built my first block last week. I understand your sentiment around it being both overwhelming and limiting. I hadn’t even heard of the “supports” API until this article.

    I think as the Block Editor has iterated so quickly, there is so much conflicting information, even within the official documentation itself. The code examples in the docs could also be vastly improved.

    With that said, the actual implementation by the team is great. If I had to build my block again it would be in a vastly shorter time now that I know what I need to do. It’s unfortunate that the initial barrier to entry is so high due to all the conflicting information and sheer overwhelming number of options.

    Articles like yours are super useful, so thank you!

  2. Great read. I’m also on the same path of starting my block journey soon. I haven’t tried this tool yet. What confuses me is how to handle basic WordPress query stuff, is it via REST or is there another approach? Also, does it make sense to buy courses like Zack Gordon has some about Gutenberg?

    • You can do that “loop stuff” with “select” or “use select”, also you can handle that with the rest API if the “select” API isn’t enough for your needs (it’s common extend the rest API if you need an advanced and complex queries).

  3. The documentation is almost useless. The examples in there are very basic and not helpful at all. The docs might be enough for building basic blocks such as a pricing table, but not for more advanced blocks that need to show dynamic data.
    Crucial functions for developing dynamic blocks (a basic feature for client work) such as getEntityRecords/getEntityRecord are an afterthought in the docs. There is just one example with them and it still uses higher-order components instead of the much simpler React hooks.
    If it weren’t for StackOverflow, I wouldn’t have gotten very far building blocks.

    • Core is welcome to use my breadcrumbs code, which is linked in that ticket. There’s over a decade of work there covering almost every imaginable scenario. I feel like if I worked on that ticket I’d have to help build an inferior server-side solution. But, if there’s interest in bundling a third-party library for this, I’d be happy to help move it along.

      Now, for the JS part, I’m highly interested in that. I’ve already learned from reading the code there. If I have something that I think would improve it, I’ll definitely pass it along.

Newsletter

Subscribe Via Email

Enter your email address to subscribe to this blog and receive notifications of new posts by email.