SKILL.md
Create a new Gutenberg block following WordPress best practices.
Pre-flight: Variation check
Before scaffolding a new block, run this check:
- Search existing blocks (
src/blocks/*) for anything conceptually similar. - Ask: would the new block differ from an existing one only by 1–3 attributes and share the same
save()output structure? - If yes → register a variation via
registerBlockVariation, not a new block. Variations have no migration cost and no deprecation debt. - If the save markup or inner-block structure actually differs → a new block is justified. Proceed.
See the "Variations vs. new blocks" section in .claude/claude.md for rationale and the consolidation pattern for sibling blocks.
Ask the User For
- Block name (e.g., "accordion", "testimonial-slider")
- Block category (e.g., "design", "widgets", "text", "media")
- Needs frontend JavaScript? (Yes/No)
- Needs dynamic rendering (PHP)? (Yes/No)
What Gets Created
- Block directory:
src/blocks/[block-name]/ block.jsonwith proper metadata and attributesindex.jsto register the blockedit.jswith editor controlssave.jswith frontend markupstyle.scssfor frontend styleseditor.scssfor editor-only stylesfrontend.js(if needed for interactivity)render.php(if dynamic rendering needed)
Before Scaffolding — Check Shared Primitives
Before generating any block code, check src/hooks/ and src/components/shared/ for primitives that already cover the patterns you're about to write. The plugin maintains shared building blocks specifically to keep new blocks consistent with the rest of the codebase. See the Shared Primitives First and Variation vs New Block sections of .claude/claude.md for the full list and the variation-vs-block decision rule.
If a new block differs from an existing one only by 1–3 attributes and shares the same save() output, register a variation in the existing block's block.json instead of creating a new block.
Critical Patterns to Follow
ALWAYS use these in edit.js:
useBlockProps()for block wrapperuseInnerBlocksProps()for nested blocks (NOT plain<InnerBlocks />)- Declarative styling (NO
useEffectfor styles)
ALWAYS include in block.json:
- Comprehensive
supportsfor FSE compatibility exampleproperty for pattern library- WordPress presets (no hardcoded colors/spacing)
Color controls:
- Use
ColorGradientSettingsDropdown(NOTPanelColorSettings) - Place in
<InspectorControls group="color"> - Require
clientIdparameter in edit function
After Creation
Block will be auto-detected by webpack - no need to modify src/index.js.
If dynamic rendering is used, add PHP registration in includes/class-plugin.php.
Build and Test
npm run build
Test in both editor and frontend.
Reference
See [BEST-PRACTICES-SUMMARY.md](../../docs/BEST-PRACTICES-SUMMARY.md) for complete patterns.