Skip to content
WordPress Block Development

WordPress Block DevelopmentSkill

Added to Onei
1 views
GPL-2.0-or-later
Repository Docs

Summary

Official WordPress skill for Gutenberg block work: block.json, attributes and serialization, dynamic rendering, and the deprecation path that keeps existing content valid.

Features

  • block.json metadata: attributes, supports, scripts and styles
  • register_block_type and register_block_type_from_metadata registration
  • Diagnoses block-invalid and attributes-not-persisting serialization bugs
  • Dynamic rendering with render.php and render_callback
  • Versioned deprecations and migrations so existing content stays valid
  • viewScript vs viewScriptModule guidance by target WordPress version
  • Deterministic helper scripts: detect_wp_project.mjs and list_blocks.mjs
  • Build tooling for @wordpress/scripts, @wordpress/create-block and wp-env

Install This Skill

Add this skill to your favorite AI agent in a few steps.

Any AI agent

This skill is plain instructions — it works with any assistant that accepts custom instructions or system prompts.

  1. Copy the skill content with the button below.
  2. Paste it into your agent's instruction file or system prompt (for example AGENTS.md, .cursorrules, or a custom instructions field).
  3. Ask the agent to apply the skill whenever the task matches.

Skill Content

Markdown Content

Copy this content and use it with your preferred AI agent

---
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

1. Run triage:
   - `node skills/wp-project-triage/scripts/detect_wp_project.mjs`
2. List blocks (deterministic scan):
   - `node skills/wp-block-development/scripts/list_blocks.mjs`
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`)
- you need conditional asset loading

Read and apply:
- `references/registration.md`

### 6) Implement edit/save/render patterns

Follow wrapper attribute best practices:

- Editor: `useBlockProps()`
- Static save: `useBlockProps.save()`
- Dynamic render (PHP): `get_block_wrapper_attributes()`

Read:
- `references/supports-and-wrappers.md`
- `references/dynamic-rendering.md` (if dynamic)

### 7) Inner blocks (block composition)

If your block is a “container” that nests other blocks, treat Inner Blocks as a first-class feature:

- Use `useInnerBlocksProps()` to integrate inner blocks with wrapper props.
- Keep migrations in mind if you change inner markup.

Read:
- `references/inner-blocks.md`

### 8) Attributes and serialization

Before changing attributes:

- confirm where the attribute value lives (comment delimiter vs HTML vs context)
- avoid the deprecated `meta` attribute source

Read:
- `references/attributes-and-serialization.md`

### 9) Migrations and deprecations (avoid "Invalid block")

If you change saved markup or attributes:

1. Add a `deprecated` entry (newest → oldest).
2. Provide `save` for old versions and an optional `migrate` to normalize attributes.

Read:
- `references/deprecations.md`

### 10) Tooling and verification commands

Prefer whatever the repo already uses:

- `@wordpress/scripts` (common) → run existing npm scripts
- `wp-env` (common) → use for local WP + E2E

Read:
- `references/tooling-and-testing.md`

## Verification

- Block appears in inserter and inserts successfully.
- Saving + reloading does not create “Invalid block”.
- Frontend output matches expectations (static: saved markup; dynamic: server output).
- Assets load where expected (editor vs frontend).
- Run the repo’s lint/build/tests that triage recommends.

## Failure modes / debugging

If something fails, start here:

- `references/debugging.md` (common failures + fastest checks)
- `references/attributes-and-serialization.md` (attributes not saving)
- `references/deprecations.md` (invalid block after change)

## Escalation

If you’re uncertain about upstream behavior/version support, consult canonical docs first:

- WordPress Developer Resources (Block Editor Handbook, Theme Handbook, Plugin Handbook)
- Gutenberg repo docs for bleeding-edge behaviors

Usage Instructions

Learn how to use this skill with different AI agents.

Generic Instructions
# project-scoped (committed with your repo)
npx skills add WordPress/agent-skills --skill wp-block-development

# available across all your projects
npx skills add WordPress/agent-skills --skill wp-block-development --global

# see everything the repository publishes
npx skills add WordPress/agent-skills --list

Description

What it is

An official agent skill from the WordPress project, teaching a coding assistant how to build and maintain Gutenberg blocks properly. It is part of WordPress/agent-skills, the WordPress organisation's own repository of expert knowledge for AI coding assistants.

Why block work needs a skill

Block development is where general-purpose coding assistants most reliably go wrong in WordPress. The failure modes are specific and unintuitive: a block that saves markup which no longer matches its save() output is invalid and WordPress will refuse it, attributes silently fail to persist when serialization is misdeclared, and the fix is almost never the one a model guesses. This skill encodes the actual procedure — including the deprecation and migration path that is the correct answer when block output has to change.

What it covers
  • block.json metadata: attributes, supports, scripts and styles, and the viewScript vs viewScriptModule distinction that depends on your target WordPress version
  • Registration through register_block_type and register_block_type_from_metadata
  • Attribute definition and serialization, and the "block invalid / not saving / attributes not persisting" class of bugs
  • Dynamic rendering via render.php and render_callback
  • Deprecations and migrations — versioned deprecated entries so existing content keeps working
  • Build tooling: @wordpress/scripts, @wordpress/create-block and wp-env
How it is built

The skill is more than a prompt. It ships deterministic helper scripts the agent runs rather than guessing — detect_wp_project.mjs to triage whether it is looking at a plugin, a theme or a full site, and list_blocks.mjs to scan the repository for every block.json and locate the block being changed. A references/ directory holds deep-dive documents on individual topics such as block-json.md and deprecations.md, loaded only when the task calls for them.

That triage-first structure is what makes it reliable across the very wide range of shapes a WordPress codebase can take.

Requirements

Targets WordPress 7.0+ on PHP 7.4.0 or newer. Needs a filesystem-capable agent with bash and node; some workflows also require WP-CLI. Licensed GPL-2.0-or-later, in keeping with WordPress itself.

Install with npx skills add WordPress/agent-skills --skill wp-block-development, project-scoped by default so it can be committed and shared with your team, or --global to make it available across all your projects.

Related Skills

Skill: claude-mem

by thedotmack

New

Persistent cross-session memory for coding agents: hooks capture each session, a local SQLite + vector store compresses it, and a mem-search skill reads it back.

1 views

The master skill in PlanetScale's official pack: runs a full read-only best-practices assessment of a database or org, then produces one evidence-backed report.

3 views
New

Build crash-safe AI agents on AgentKit and step.ai — durable tool calls, human-in-the-loop approval, realtime progress, and when not to reach for an agent loop at all.

3 views

Inngest's durable-execution playbook as an agent skill — steps and memoisation, event and cron triggers, idempotency, cancellation, retries and non-retriable errors.

2 views
Browse all skills →