Technical
Gutenberg Advanced Blocks Without Losing Your Mind
The WordPress block editor went from 'toy I tolerated' to 'tool I build for' over the last year. Most of what I build for clients now is custom blocks, not classic shortcodes. The advanced side of the API is well-documented but poorly organized. Here is the minimal path I follow to ship real blocks.
The Modern Starter
Use @wordpress/create-block for the scaffold. It gives you a block.json-based modern setup with build tooling that matches current WordPress. Skip the older register_block_type PHP-only path unless you have a specific reason.
npx @wordpress/create-block my-advanced-blockThis produces block.json, a React edit component, a save function, a PHP registration file, and the webpack config for the build. Everything I need to start modifying instead of scaffolding.
The Attributes Pattern
Attributes are where most blocks fall apart in production. The rules that have kept mine stable:
- Every attribute gets a
defaultvalue. Missing defaults cause editor crashes when older posts are rendered with a newer block version. - Every attribute gets a type:
string,number,boolean,array,object. Untyped attributes leak into frontend rendering as surprises. - New attributes land as optional with a default. Breaking old content is a Bad Day.
Dynamic Rendering
For anything that pulls live data, I render in PHP via render_callback in block.json, not in the save function. This keeps the database content minimal and the rendering up-to-date. The save function returns null for dynamic blocks.
{
"name": "plai/latest-posts",
"render": "file:./render.php",
"attributes": {
"count": {"type": "number", "default": 5},
"category": {"type": "string", "default": ""}
}
}Inspector Controls
Every non-trivial block has settings in the right sidebar. Use the InspectorControls component and group related settings into PanelBody sections. Users who do not open the panel still get a working block with the defaults.
The Test That Reveals Problems
Create a post using the block. Save. Update the block plugin to a new version with added or changed attributes. Reload the post. Can you still edit it without errors? If yes, your attribute migration is sound. If no, you need a deprecation. The block deprecation docs cover this cleanly.
Why Bother
Custom blocks give clients real control over the page structure while keeping the design system consistent. Shortcodes are opaque; blocks are visible and editable. That difference alone earns the investment.
Shipping as a Plugin
I package client blocks as a plugin, not inside a theme. Themes change; blocks persist through redesigns. A plugin-based block survives a future theme switch without the client losing any content layout. This separation is the single most important operational decision I make on WordPress projects. It keeps the content layer portable and the presentation layer swappable, which is the division every site needs eventually.
RELATED READING
The Consulting Shift I Am Making In Year Two
After a year of writing and building, my consulting practice is changing shape. Shorter engagements. Sharper outcomes.
ReadThe Frontend Shift: Shipping Less JavaScript In Year Two
A year ago I reached for Next.js for everything. This year I often reach for nothing.
ReadThe Serverless Lesson I Would Write On A Sticky Note
After a year of shipping serverless projects, one rule explains most of the wins and all of the losses.
Read