Inner block protocol

Sounds big? But it’s actually very simple. And I think we figured out the solution for block reusability and extensibility. The name is not finalized anyway. The problem We usually start with one block to do one thing and do…


Sounds big? But it’s actually very simple. And I think we figured out the solution for block reusability and extensibility.

The name is not finalized anyway.

The problem

We usually start with one block to do one thing and do it well. But what if a new block need something similar to existing ones? Some real examples from WooCommerce Core:

  • Product Gallery has the Next/Previous Buttons block, then later on, Product Collection introduces the carousel style and need the same buttons. We eventually update the Next/Previous Buttons block to work inside Product Collection.
  • Product Filters block has Chips style and it works across multiple filter blocks. Good. Later on we need the some chips for Add to Cart + Options block. We ended up having a similar block for Add to Cart + Options. Not good.

It should be the exactly same block inside multiple parents. You don’t want to button here looks different from the one there. You also don’t want to maintain two blocks doing the same thing. Next/Previous Buttons is the exactly the same block, but we have to modify it to make it work inside new parent. We don’t want that. We want to create a block once and reuse it, not everywhere, but multiple places, and even in the future.

The solution

2 layers, 1 contract. Parent blocks, the logic layer, prepare the data. Inner blocks, the presentational layer, display the data. Data passed down through block context has to follow the contract.

The inner presentational blocks now don’t attach to parent, they attach to the contract, the data they display.

#64585: is our first step applying the protocol. Filter blocks now implement several protocols:

  • Selectable items: for Attribute, Taxonomy, Status, and Rating filter blocks.
  • Removable items: for Active filters block.
  • Range input: for price filter block.

The shape of context passed down to inner block is the same as before, but we now we have a contract. Inner blocks following a protocol should work inside parents implement it.

Want more details? You can (or have your agent) looks at inner-block-protocols.md.

The application

  • Reusability and forward compatibility: as long as the future parent/inner block implement the protocol, it should work with existing ones implementing the same protocol.
  • Parent block can implement more than one protocol. It’s just context data after all. Think about the price filter, it’s a range input slider now, only. But we might add selectable items to it, then we can have predefined price ranges using Chips or List blocks or any inner blocks implement that protocol.
  • I believe the block extensibility should be done through blocks, inner blocks for specific. We did it for Product Filters. WooCommerce provides parent filter blocks that handle of internal business logics and prepare the data for inner block to use. Developers can create new inner blocks to present the data the way they need. Core inner blocks get the same treatment as custom blocks.
  • With the capable of current LLM models now, it’s even easier to create new inner blocks. Give your agent the spec and it should be able to create new inner blocks for you.

What’s next

We still mark the new protocol as experimental to stabilize it a little more. It needs to work for core first to convince us it works for developers. We’re trying to be the best ourselves when working on this. I think we’re getting it, but I can be wrong, let’s see.


cat /etc/signature

— tung@tungdu