From superpowers-sage
Builds native Gutenberg blocks without ACF — block.json, edit/save JS, InnerBlocks, transforms, block variations, dynamic PHP render, and @wordpress/scripts.
How this skill is triggered — by the user, by Claude, or both
Slash command
/superpowers-sage:wp-block-nativeThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
When building editor blocks that require capabilities beyond what ACF Composer provides: InnerBlocks nesting, block transforms, block variations, JS-heavy editor UI, or block deprecations. Also use when you need fine-grained control over the editor experience or when a block's primary complexity is in its editor behavior rather than its field configuration.
When building editor blocks that require capabilities beyond what ACF Composer provides: InnerBlocks nesting, block transforms, block variations, JS-heavy editor UI, or block deprecations. Also use when you need fine-grained control over the editor experience or when a block's primary complexity is in its editor behavior rather than its field configuration.
| Requirement | ACF Composer | Native Block |
|---|---|---|
| Complex field groups (repeaters, flexible content) | Best choice | Avoid |
| InnerBlocks (nested block areas) | Not supported | Required |
| Block transforms (convert between block types) | Not supported | Required |
| Block variations (same block, different presets) | Limited | Full support |
| JS-heavy editor controls | Limited | Full support |
| Block deprecations (safe markup changes) | Not applicable | Required |
| Quick data-entry blocks | Best choice | Overkill |
Both can coexist in the same project. ACF blocks and native blocks appear side by side in the inserter.
resources/
scripts/
editor/
blocks/
hero/
index.js # Block registration (edit + save)
edit.js # Editor component
save.js # Save component (or null for dynamic)
style.css # Front-end styles
editor.css # Editor-only styles
block.json # Block metadata
See references/block-json-native.md for full field reference and attribute source types.
Use apiVersion 3 for WordPress 6.3+. Key fields: name, attributes, supports, editorScript, render.
See references/edit-save.md for complete edit/save examples, deprecations, and ServerSideRender.
edit — React component; interactive; output not storedsave — pure function; stored HTML; must match on re-parseSee references/dynamic-blocks.md for PHP render templates, Blade integration, and InnerBlocks with dynamic rendering.
For blocks that query WordPress data, set save: () => null and use the render field in block.json:
// render.php — receives $attributes, $content, $block
<div <?php echo get_block_wrapper_attributes(['class' => 'hero']); ?>>
<?php echo $content; ?>
</div>
See references/vite-integration.md for Vite configuration, @wordpress/* externals, and the single-bundle vs per-block entry pattern.
Key: declare @wordpress/* packages as externals in Vite — do not bundle them. Enqueue via enqueue_block_editor_assets:
add_action('enqueue_block_editor_assets', function () {
wp_enqueue_script(
'sage-editor-blocks',
Vite::asset('resources/scripts/editor/index.js'),
['wp-blocks', 'wp-element', 'wp-block-editor', 'wp-components'],
null,
true
);
});
import { useBlockProps, useInnerBlocksProps } from '@wordpress/block-editor';
export default function Edit() {
const blockProps = useBlockProps({ className: 'card-grid' });
const innerBlocksProps = useInnerBlocksProps(blockProps, {
allowedBlocks: ['sage/card', 'core/paragraph'],
template: [['sage/card', {}], ['sage/card', {}]],
templateLock: false,
});
return <div {...innerBlocksProps} />;
}
| Symptom | Cause | Fix |
|---|---|---|
| "This block contains unexpected or invalid content" | Save function output does not match stored HTML | Fix save function or add a deprecation |
| Block not appearing in inserter | block.json not found or editor script not enqueued | Check file paths and script registration |
| Styles not applying | Missing get_block_wrapper_attributes() or useBlockProps() | Block supports require these wrappers |
| InnerBlocks empty on front end | $content variable not echoed in render template | Add echo $content to PHP render |
| Editor script errors | Missing WordPress script dependencies | Ensure wp-blocks, wp-element, wp-block-editor are listed as dependencies |
save function exactly reproduces the old output. Use browser console to compare expected vs actual HTML.register_block_type() silently fails, enable WP_DEBUG and check for errors. Common cause: invalid block.json syntax or missing required fields.npx claudepluginhub hekivo/superpowers-sageGenerates WordPress blocks from scratch using templates from reference files. Guides dynamic block creation with InnerBlocks, viewScript, and data-* attributes.
Scaffolds ACF Composer blocks with custom element architecture, scoped CSS, theme variations, and JS lifecycle. Use when creating new Gutenberg blocks in Sage-based WordPress themes.
Guides modern WordPress plugin development: scaffolding, debugging, testing, and refactoring. Covers WooCommerce, Gutenberg blocks, custom post types, WordPress REST API, hooks, admin pages, WPCS, PHPUnit, Playwright, and wp-scripts.