Use when developing WordPress (Gutenberg) blocks: block.json metadata, register_block_type(_from_metadata), attributes/serialization, supports, dynamic rendering (render.php/render_callback), deprecations/migrations, viewScript vs viewScriptModule, and
Installs just this skill. Get the whole plugin for auto-invocation.
ā” How it fires
How this skill gets triggered: by you, by Claude, or both.
Fires itselfClaude auto-loads it when your prompt matches the work.
You can call itInvoke it directly when you want it.
Slash command/wp-block-development
šļø Context preview
The summary Claude sees to decide when to auto-load this skill.
Use when developing WordPress (Gutenberg) blocks: block.json metadata, register_block_type(_from_metadata), attributes/serialization, supports, dynamic rendering (render.php/render_callback), deprecations/migrations, viewScript vs viewScriptModule, and
---name: wp-block-development
description: "Use when developing WordPress (Gutenberg) blocks: block.json metadata, register_block_type(_from_metadata), attributes/serialization, supports, dynamic rendering (render.php/render_callback), deprecations/migrations, viewScript vs viewScriptModule, and @wordpress/scripts/@wordpress/create-block build and test workflows."
compatibility: "Targets WordPress 7.0+ (PHP 7.4.0+). Filesystem-based agent with bash + node. Some workflows require WP-CLI."
---# WP Block Development
## When to use
Use this skill for block work such as:
- creating a new block, or updating an existing one
- changing `block.json` (scripts/styles/supports/attributes/render/viewScriptModule)
- fixing āblock invalid / not saving / attributes not persistingā
- adding dynamic rendering (`render.php` / `render_callback`)
- block deprecations and migrations (`deprecated` versions)
- build tooling for blocks (`@wordpress/scripts`, `@wordpress/create-block`, `wp-env`)
## Inputs required
- Repo root and target (plugin vs theme vs full site).
- The block name/namespace and where it lives (path to `block.json` if known).
- Target WordPress version range (especially if using modules / `viewScriptModule`).
## Procedure
### 0) Triage and locate blocks
3. Identify the block root (directory containing `block.json`) youāre changing.
If this repo is a full site (`wp-content/` present), be explicit about *which* plugin/theme contains the block.
### 1) Create a new block (if needed)
If you are creating a new block, prefer scaffolding rather than hand-rolling structure:
- Use `@wordpress/create-block` to scaffold a modern block/plugin setup.
- If you need Interactivity API from day 1, use the interactive template.
Read:
- `references/creating-new-blocks.md`
After scaffolding:
1. Re-run the block list script and confirm the new block root.
2. Continue with the remaining steps (model choice, metadata, registration, serialization).
### 2) Ensure apiVersion 3 (WordPress 6.9+)
WordPress 6.9 enforces `apiVersion: 3` in the block.json schema. Blocks with apiVersion 2 or lower trigger console warnings when `SCRIPT_DEBUG` is enabled.
**Why this matters:**
- WordPress 7.0 will run the post editor in an iframe regardless of block apiVersion.
- apiVersion 3 ensures your block works correctly inside the iframed editor (style isolation, viewport units, media queries).
**Migration:** Changing from version 2 to 3 is usually as simple as updating the `apiVersion` field in `block.json`. However:
- Test in a local environment with the iframe editor enabled.
- Ensure any style handles are included in `block.json` (styles missing from the iframe won't apply).
- Third-party scripts attached to a specific `window` may have scoping issues.
Read:
- `references/block-json.md` (apiVersion and schema details)
### 3) Pick the right block model
- **Static block** (markup saved into post content): implement `save()`; keep attributes serialization stable.
- **Dynamic block** (server-rendered): use `render` in `block.json` (or `render_callback` in PHP) and keep `save()` minimal or `null`.
- **Interactive frontend behavior**:
- Prefer `viewScriptModule` for modern module-based view scripts where supported.
- If you're working primarily on `data-wp-*` directives or stores, also use `wp-interactivity-api`.
### 4) Update `block.json` safely
Make changes in the blockās `block.json`, then confirm registration matches metadata.
For field-by-field guidance, read:
- `references/block-json.md`
Common pitfalls:
- changing `name` breaks compatibility (treat it as stable API)
- changing saved markup without adding `deprecated` causes āInvalid blockā
- adding attributes without defining source/serialization correctly causes āattribute not savingā
### 5) Register the block (server-side preferred)
Prefer PHP registration using metadata, especially when:
- you need dynamic rendering
- you need translations (`wp_set_script_translations`)