Ask the Bartender: What Happens When Block Markup Changes?

I’m a developer that has started developing with Gutenberg recently. There are a bunch of amazing benefits and features, but there are also a ton of drawbacks, inconsistencies, as well as absolutely awful and outdated documentation.

One of the worst aspects of Gutenberg from a developer perspective has been block validation. Consider the following scenario. I build a custom (non-dynamic) JavaScript-based block, and a CMS editor adds the block to thousands of pages. What happens when or if I need to update the markup of the block?

By default, all of the blocks will enter a state of invalidation and not reflect on the front-end of the site. The CMS editor would have to go into thousands of pages and manually click the button which allows the block to be recovered.

Block deprecations have been suggested as a way to resolve this, but the API is poorly documented, confusing, and seems like it would become unmaintainable in the long term with more than a few deprecations.

Shouldn’t there either be a way for block developers to opt-out of the validation process or a global way to recover blocks?
PJ

You are certainly not holding anything back, PJ. While much of this is a bit more technical than I typically like to cover here at the Tavern, I decided to reach out to Riad Benguella, one of the lead Gutenberg developers, for more insight into the situation.

Before diving into his response, I have given one aspect of your question some thought. There are times when developers need to deprecate old markup and move onto something new. However, this should not happen often. Generally, it is a sign of poor architecture if the HTML needs to be overhauled regularly. This also leads to other issues, such as a third party not being able to maintain stylistic changes.

When developing blocks or any type of application that outputs front-end code, you need to think about what that should look like today and in 10 years. What happens if a user adds some custom CSS to style your block and the block’s HTML structure has changed? From their perspective, your block update has broken their site. The same could be said for another plugin that extends your plugin in some way.

Ask any theme author how frustrating it is any time Gutenberg/WordPress changes its block output. While it has improved in the last couple of years, styling blocks for the editor and front-end has often been a maintenance nightmare.

As a developer, I have always tried to think through any real-world consequences of making these changes from a user’s perspective. That should happen from Day #1, not after you have released your project.

Doing this adds time to the early project when you are just trying to get it out the door and into users’ hands. This is where taking a pre-release step back helps. Get away from the computer. Go on a walk. Think about the architecture of your project and whether it is ideal for the long term.

“For the block versioning/updates, it’s indeed one of the areas of the Gutenberg APIs where we needed to make architectural tradeoffs, and we decided to favor the user experience over the developer’s,” said Benguella.

Regardless of your development method, following the project’s approach of a user-first experience will help in the long term.

“To understand the problem properly, one needs to understand how blocks work and are edited,” said Benguella. “Block instances are a JSON object, and the editor UI manipulate that JSON, but in order to stay backward compatible, to ensure the preservation of user’s content in the most readable format, and to embrace web standards as much as possible, the block editor doesn’t store the JSON object but an HTML serialization of it in post_content.”

That serialization is parsed and converted to JSON when the editor reloads the content to edit again. In the final stages of parsing, it is up to the block author to decide how to save and parse the object.

“Now, imagine if a user altered the saved HTML (serialization) and just put any random content there,” said Benguella. “The block might not be able to parse the HTML properly because it doesn’t match its expectations (what has been defined by the block author), which means recreating that JSON object in order to be manipulated won’t be possible at this point.”

When this happens, the block editor provides the user with an interface to make an informed decision. They can attempt to “force parse” the block JSON or convert it to an HTML or Classic block.

Invalid block after altering the markup.

This same type of invalidation can happen when a plugin developer updates their block. However, instead of the saved HTML changing, the developer changed the “expectations” of the block — altering how it gets saved and parsed.

“Which is why we ask block developers to provide block deprecations representing the old markup of the same block,” said Benguella. “Deprecations can also be thought of as valid, alternate sources for the same block. This allows the editor to parse the old markup when loaded and save the new markup back if an update is made to the block.”

WordPress has block deprecation documentation. However, it is not thorough. The best source of seeing real-world deprecations is looking through Gutenberg’s block library. Deprecated blocks have a deprecated.js file.

Benguella said that this system can be frustrating for block authors. This is especially evident in a development environment when making changes. This has lead developers to ask for a method of disabling the validation algorithm.

“It’s something we don’t want to provide at the moment because, as explained above, the validation is also important when markup changes for another reason (external edit, another editor, etc.),” he said. “So it may cause content loss for users without them being aware of anything. The preference right now is given to user awareness.”

The team has improved the validation system over time, allowing for small changes that do not break the block state. There is also an open ticket for improvements in the future.