| name | add-block-pattern |
| description | Register a block pattern in a theme or plugin, using the WordPress 6.0+ file-based pattern system. |
Add a Block Pattern
Register a new block pattern using WordPress's file-based pattern auto-loader (6.0+). Covers pattern file structure, category registration, and the conventions for naming and markup.
Inputs
| Input | Required | Notes |
|---|
| Title | Yes | Human-readable name shown in the inserter, e.g. Hero with CTA |
| Slug | Yes | Machine name, e.g. hero-cta. The full pattern name will be {text-domain}/{slug} |
| Description | No | One sentence shown in the inserter tooltip |
| Category | Yes | Existing WP category (featured, text, gallery, etc.) or a new custom one |
| Target package | Yes | Theme or plugin in packages/ |
| Keywords | No | Comma-separated terms to aid discoverability in the inserter |
| Block markup | Yes | The block content to scaffold — describe the layout if not provided |
If any required inputs are missing, ask for them before writing any code.
Step 1 — Confirm the auto-loader is in place
File-based patterns are auto-loaded by WordPress 6.0+ from a patterns/ directory at the root of a theme. For plugins, patterns must be registered programmatically (see Step 3 variant).
- Theme: confirm a
patterns/ directory exists (or create it).
- Plugin: patterns go in
src/patterns/ and are registered via init.
Step 2 — Create the pattern file (theme)
Create patterns/{slug}.php in the theme root. The file header comment registers the pattern — no PHP function call needed:
<?php
?>
<!-- wp:cover {"minHeight":60,"minHeightUnit":"vh","align":"full"} -->
<div class="wp-block-cover alignfull">
<!-- wp:heading {"level":1} -->
<h1 class="wp-block-heading">Your headline here</h1>
<!-- /wp:heading -->
<!-- wp:buttons -->
<div class="wp-block-buttons">
<!-- wp:button -->
<div class="wp-block-button"><a class="wp-block-button__link wp-element-button">Call to action</a></div>
<!-- /wp:button -->
</div>
<!-- /wp:buttons -->
</div>
<!-- /wp:cover -->
Header field reference:
| Field | Required | Notes |
|---|
Title | Yes | Shown in the block inserter |
Slug | Yes | Must be {text-domain}/{slug} — unique across all patterns |
Categories | Yes | Comma-separated. Use existing WP categories where possible |
Keywords | No | Aids inserter search |
Viewport Width | No | Preview canvas width in pixels |
Block Types | No | Restricts the pattern to the inserter for those block types |
Post Types | No | Restricts to specific post type editors |
Inserter | No | Set to false to hide from the inserter (use as a template only) |
Step 3 — Register the pattern from a plugin (alternative)
For plugins, register via register_block_pattern() in a hooks() method:
public function hooks(): void {
add_action( 'init', [ $this, 'register_patterns' ] );
}
public function register_patterns(): void {
\register_block_pattern(
'{plugin-slug}/{slug}',
[
'title' => __( 'Hero with CTA', '{plugin-slug}' ),
'description' => __( 'Full-width hero with heading and button.', '{plugin-slug}' ),
'categories' => [ 'featured' ],
'keywords' => [ 'hero', 'banner', 'cta' ],
'content' => '<!-- wp:cover -->...<!-- /wp:cover -->',
]
);
}
Step 4 — Register a custom category (if needed)
If the pattern uses a category that does not exist in WordPress core, register it via init before registering the pattern:
add_action( 'init', function (): void {
\register_block_pattern_category(
'{text-domain}-{category-slug}',
[ 'label' => __( 'Category Label', '{text-domain}' ) ]
);
} );
Built-in WP categories that do not require registration: featured, text, gallery, buttons, columns, query, portfolio, social, posts, banner, header, footer, media.
Step 5 — Lint and verify
composer lint
composer lint-fix
composer lint
Verify in WordPress:
- Open the block inserter — the pattern appears under its category.
- Inserting the pattern renders the correct markup in the editor.
- No console errors or block validation warnings.
Conventions
- Slug format: always
{text-domain}/{slug} — prefix prevents collisions with Core and other plugins
- Titles: sentence case, English — translated via
.pot/.po files
- No PHP logic in pattern files: pattern files output block markup only — use
<!-- wp: --> comments, not rendered HTML
- No inline styles with hardcoded colours: use CSS custom properties from
theme.json (var(--wp--preset--color--primary))
- Keep patterns focused: one layout idea per pattern — do not create catch-all patterns that try to cover every variant
Output
A patterns/{slug}.php file (theme) or a registered pattern via register_block_pattern() (plugin). The pattern is visible in the block inserter under its assigned category and inserts valid, linting-clean block markup.