Use when developing WordPress (Gutenberg) blocks: block.json metadata, register_block_type, attributes/serialization, supports, dynamic rendering (render.php), deprecations/migrations, InnerBlocks,...
Use this skill for block work such as:
block.json (scripts/styles/supports/attributes/render)render.php / render_callback)deprecated versions)@wordpress/scripts, @wordpress/create-block)block.json if known).viewScriptModule / apiVersion 3).block.json filesregister_block_type callsblock.json)If creating a new block, prefer scaffolding:
npx @wordpress/create-block@latest my-custom-block
For interactive blocks, use the interactive template.
Read:
references/creating-blocks.mdWordPress 6.9 enforces apiVersion: 3 in block.json schema. Blocks with apiVersion 2 or lower trigger console warnings when SCRIPT_DEBUG is enabled.
Why this matters:
Migration from apiVersion 2:
apiVersion field in block.json to 3block.json (styles missing from the iframe won't apply)window may have scoping issues{
"apiVersion": 3,
"name": "my-plugin/my-block",
"...": "..."
}
Read:
references/block-json.mdsave()render in block.json and keep save() minimal or nullviewScriptModule for modern module-based view scriptsviewScript vs viewScriptModule:
| Property | viewScript |
viewScriptModule |
|---|---|---|
| Module type | Classic script | ES Module |
| Loading | Synchronous | Async/deferred |
| Use for | Legacy/compatibility | Interactivity API, modern JS |
| Dependencies | Manual registration | Import statements |
{
"viewScript": "file:./view.js",
"viewScriptModule": "file:./view.js"
}
Prefer viewScriptModule for:
@wordpress/interactivity)For field-by-field guidance:
Read:
references/block-json.mdCommon pitfalls:
name breaks compatibility (treat it as stable API)deprecated causes "Invalid block"Prefer PHP registration using metadata for:
wp_set_script_translations)Read:
references/registration.mdFollow wrapper attribute best practices:
useBlockProps()useBlockProps.save()get_block_wrapper_attributes()Read:
references/edit-save-render.mdIf your block is a container that nests other blocks:
useInnerBlocksProps() to integrate inner blocks with wrapper propsRead:
references/inner-blocks.mdRead:
references/patterns-variations.mdIf you change saved markup or attributes:
deprecated entry (newest → oldest)save for old versions and optional migrateRead:
references/deprecations.mdsource definition, wrong attribute type, serialization mismatcheditorStyle in block.json, wrong asset pathRead:
references/debugging.mdFor canonical detail, consult: