
What Are Block Patterns and How to Create Your Own in WordPress?
Every site has layouts that get rebuilt over and over. A hero section with a heading, a sentence, and two buttons. A three-column feature grid. A testimonial with a photo and a quote. Editors either rebuild them from scratch each time, getting the spacing slightly different on every page, or they copy and paste from an older page and drag along content that does not belong. Neither approach scales, and both slowly erode the design.
Block patterns fix this. A pattern is a saved arrangement of blocks that anyone can insert with two clicks and then edit like normal content. The layout, colors, and spacing come pre-built; only the words and images change.
This article explains what block patterns are and how they differ from synced patterns and templates, how to create patterns in the editor without code, how to ship them in a theme as pattern files, how to register them from a plugin with register_block_pattern(), how to organize them with categories and make them appear when a new page is created, and how to control which patterns editors see.
What Is a Block Pattern?
A block pattern is a predefined group of blocks, stored as block markup, that you insert into a post, page, or template. Once inserted, the blocks are independent copies: editing them changes only that page. The pattern itself is a starting point, not a live link.
WordPress has several kinds of patterns:
| Type | Where it comes from | Edits sync across pages? |
|---|---|---|
| Core patterns | Bundled with WordPress | No |
| Pattern Directory patterns | Loaded from WordPress.org | No |
| Theme patterns | Files in a theme's patterns/ folder | No |
| Plugin patterns | Registered with register_block_pattern() | No |
| Unsynced user patterns | Created by users in the editor | No |
| Synced patterns | Created by users in the editor | Yes |
Synced patterns (formerly called reusable blocks) are different: every instance stays linked to the original, so editing one updates all of them. They suit content that must be identical everywhere, like a newsletter signup or a disclaimer. They are covered separately in how to use synced patterns in WordPress. This article focuses on regular, unsynced patterns used as layout starting points.
Patterns are also different from templates. A template controls the structure of a whole view, such as every single post. A pattern is inserted into content once and then belongs to that page.
Inserting a Pattern
- Open a post or page in the editor.
- Click the + (Block Inserter) button in the top toolbar.
- Switch to the Patterns tab.
- Browse by category or search, then click a pattern to insert it.
You can also type / in an empty paragraph and search for a pattern by name.
Creating a Pattern in the Editor (No Code)
The quickest way to create a pattern is to design it in the editor and save it:
- Build the layout in any post or page, using Group, Columns, Heading, Buttons, and other blocks.
- Select the outer block (usually a Group) or several blocks at once.
- Open the block toolbar's Options menu (three dots) and choose Create pattern.
- Enter a name, choose one or more categories, and turn the Synced toggle off for a regular pattern.
- Click Add.
The pattern now appears in the inserter's Patterns tab under My patterns and in your chosen categories. It is stored in the database as a wp_block post, so it belongs to this site only.
To manage these patterns later, open Dashboard > Appearance > Editor > Patterns on block themes, or go to the patterns list from the editor's options menu on classic themes. From there you can rename, edit, duplicate, export to JSON, and delete patterns. The JSON export can be imported on another site, which is a simple way to share patterns without code.
Creating Patterns in a Theme
For patterns that are part of a design, ship them with the theme. Any PHP file in a theme's patterns/ folder is registered automatically. The file's header comment provides the metadata:
<?php
// wp-content/themes/my-theme/patterns/feature-grid.php
/**
* Title: Feature Grid
* Slug: my-theme/feature-grid
* Categories: featured, columns
* Keywords: features, services, grid
* Description: Three columns with an icon, heading, and short description.
* Viewport Width: 1200
*/
?>
<!-- wp:group {"align":"wide","layout":{"type":"constrained"}} -->
<div class="wp-block-group alignwide">
<!-- wp:heading {"textAlign":"center"} -->
<h2 class="wp-block-heading has-text-align-center"><?php echo esc_html__( 'Why choose us', 'my-theme' ); ?></h2>
<!-- /wp:heading -->
<!-- wp:columns {"align":"wide"} -->
<div class="wp-block-columns alignwide">
<!-- wp:column -->
<div class="wp-block-column">
<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading"><?php echo esc_html__( 'Fast', 'my-theme' ); ?></h3>
<!-- /wp:heading -->
<!-- wp:paragraph -->
<p><?php echo esc_html__( 'Pages load quickly on every device.', 'my-theme' ); ?></p>
<!-- /wp:paragraph -->
</div>
<!-- /wp:column -->
<!-- wp:column -->
<div class="wp-block-column">
<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading"><?php echo esc_html__( 'Secure', 'my-theme' ); ?></h3>
<!-- /wp:heading -->
<!-- wp:paragraph -->
<p><?php echo esc_html__( 'Hardened hosting and regular updates.', 'my-theme' ); ?></p>
<!-- /wp:paragraph -->
</div>
<!-- /wp:column -->
<!-- wp:column -->
<div class="wp-block-column">
<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading"><?php echo esc_html__( 'Supported', 'my-theme' ); ?></h3>
<!-- /wp:heading -->
<!-- wp:paragraph -->
<p><?php echo esc_html__( 'Real people answer your questions.', 'my-theme' ); ?></p>
<!-- /wp:paragraph -->
</div>
<!-- /wp:column -->
</div>
<!-- /wp:columns -->
</div>
<!-- /wp:group -->
The header fields WordPress reads:
| Field | Required | Purpose |
|---|---|---|
Title | Yes | Name shown in the inserter |
Slug | Yes | Unique ID, prefixed with the theme slug |
Categories | No | Comma-separated category slugs |
Keywords | No | Extra search terms |
Description | No | Shown to screen readers and in some views |
Viewport Width | No | Width of the preview thumbnail, in pixels |
Block Types | No | Blocks the pattern is suggested for, such as core/post-content |
Post Types | No | Limits the pattern to certain post types |
Template Types | No | Suggests the pattern when creating templates, such as 404 |
Inserter | No | Set to no to hide it from the inserter |
Because the file is PHP, you can translate text with esc_html__() and reference theme images with get_theme_file_uri():
<?php
// wp-content/themes/my-theme/patterns/hero-image.php (excerpt)
?>
<!-- wp:image {"sizeSlug":"large"} -->
<figure class="wp-block-image size-large">
<img src="<?php echo esc_url( get_theme_file_uri( 'assets/images/hero.webp' ) ); ?>" alt="<?php echo esc_attr__( 'Team working together', 'my-theme' ); ?>" />
</figure>
<!-- /wp:image -->
Getting the Markup Right
Do not hand-write complex block markup. If the HTML does not match what each block's save function produces, the editor reports invalid content when the pattern is inserted. The reliable workflow:
- Build the layout in the editor.
- Select all its blocks, open Options, and choose Copy. Or switch the whole post to the Code editor with Ctrl+Shift+Alt+M (Cmd+Shift+Option+M on Mac).
- Paste the markup into your pattern file below the header.
- Replace hard-coded text with translation functions and image URLs with
get_theme_file_uri().
On block themes, the Create Block Theme plugin can also save user-created patterns directly into the theme's patterns/ folder.
Registering Patterns from a Plugin
Patterns that should survive a theme switch, like a company's standard call-to-action, belong in a plugin. Register them on init with register_block_pattern():
<?php
// wp-content/plugins/company-patterns/company-patterns.php
/**
* Plugin Name: Company Patterns
* Description: Shared block patterns for company sites.
* Version: 1.0.0
* Text Domain: company-patterns
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
function company_patterns_register() {
register_block_pattern_category(
'company',
array( 'label' => __( 'Company', 'company-patterns' ) )
);
register_block_pattern(
'company-patterns/cta',
array(
'title' => __( 'Call to Action', 'company-patterns' ),
'description' => __( 'A centered heading with a contact button.', 'company-patterns' ),
'categories' => array( 'company', 'call-to-action' ),
'keywords' => array( 'contact', 'cta' ),
'viewportWidth' => 1000,
'content' => '<!-- wp:group {"layout":{"type":"constrained"}} -->
<div class="wp-block-group"><!-- wp:heading {"textAlign":"center"} -->
<h2 class="wp-block-heading has-text-align-center">' . esc_html__( 'Ready to start your project?', 'company-patterns' ) . '</h2>
<!-- /wp:heading -->
<!-- wp:buttons {"layout":{"type":"flex","justifyContent":"center"}} -->
<div class="wp-block-buttons"><!-- wp:button -->
<div class="wp-block-button"><a class="wp-block-button__link wp-element-button" href="/contact/">' . esc_html__( 'Contact us', 'company-patterns' ) . '</a></div>
<!-- /wp:button --></div>
<!-- /wp:buttons --></div>
<!-- /wp:group -->',
)
);
}
add_action( 'init', 'company_patterns_register' );
For long patterns, keep the markup in a separate file and load it with output buffering, which keeps the PHP readable:
<?php
// wp-content/plugins/company-patterns/company-patterns.php (alternative)
function company_patterns_get_content( $file ) {
ob_start();
include __DIR__ . '/patterns/' . $file;
return ob_get_clean();
}
function company_patterns_register_from_files() {
register_block_pattern(
'company-patterns/pricing',
array(
'title' => __( 'Pricing Table', 'company-patterns' ),
'categories' => array( 'company' ),
'content' => company_patterns_get_content( 'pricing.php' ),
)
);
}
add_action( 'init', 'company_patterns_register_from_files' );
Only include files from your own plugin folder with fixed names, never from user input.
Pattern Categories
Categories organize the Patterns tab. Core includes categories such as banner, buttons, call-to-action, columns, featured, footer, gallery, header, text, and query. Register your own with register_block_pattern_category(), as in the plugin example above. A pattern can belong to several categories.
Theme patterns can use a custom category too. Register the category in functions.php, then list its slug in the pattern file's Categories header.
Starter Patterns for New Pages and Templates
Patterns can appear automatically when someone creates a new page. Add core/post-content to the Block Types header and limit the pattern to pages:
<?php
// wp-content/themes/my-theme/patterns/page-about.php
/**
* Title: About Page
* Slug: my-theme/page-about
* Categories: featured
* Block Types: core/post-content
* Post Types: page
* Viewport Width: 1200
*/
?>
<!-- wp:heading {"level":1} -->
<h1 class="wp-block-heading"><?php echo esc_html__( 'About us', 'my-theme' ); ?></h1>
<!-- /wp:heading -->
<!-- wp:paragraph -->
<p><?php echo esc_html__( 'Tell visitors who you are and what you do.', 'my-theme' ); ?></p>
<!-- /wp:paragraph -->
When an editor creates a new page, WordPress offers a modal with this pattern and any other starter patterns. Choosing one fills the page with the layout.
The Template Types header does the same for templates in the Site Editor. A pattern with Template Types: 404 is suggested when someone creates or replaces the 404 template.
Controlling Which Patterns Appear
Large pattern libraries can overwhelm editors. A few snippets help keep the inserter focused. Put these in a theme's functions.php or a small plugin:
<?php
// wp-content/themes/my-theme/functions.php
// Remove the patterns bundled with WordPress core.
function my_theme_remove_core_patterns() {
remove_theme_support( 'core-block-patterns' );
}
add_action( 'after_setup_theme', 'my_theme_remove_core_patterns' );
// Stop loading patterns from the WordPress.org Pattern Directory.
add_filter( 'should_load_remote_block_patterns', '__return_false' );
// Remove a single pattern by name.
function my_theme_unregister_patterns() {
unregister_block_pattern( 'core/query-standard-posts' );
}
add_action( 'init', 'my_theme_unregister_patterns', 20 );
Block themes can also pull specific Pattern Directory patterns into their library by slug through the patterns array in theme.json, which is handy for curating a small set without copying markup.
To hide a pattern from the inserter but still use it elsewhere, for example inside a template, set Inserter: no in its header. You can then reference it from template markup with the Pattern block: <!-- wp:pattern {"slug":"my-theme/feature-grid"} /-->.
Pattern Design Tips
- Use theme presets, not hard-coded values. Pick colors, font sizes, and spacing from the palette and scales defined in
theme.jsonso patterns adapt when the theme or a style variation changes. - Write realistic placeholder text. "Lorem ipsum" gets published by accident. Short, plausible copy makes the pattern easier to understand and safer to ship.
- Keep patterns small and composable. A hero, a feature grid, and a CTA are more useful as three patterns than as one giant page.
- Name and categorize clearly. Editors search by what they want, such as "pricing" or "testimonial". Add keywords.
- Lock structure where needed. Block locking can prevent editors from moving or removing key parts of a pattern while still letting them edit text.
Common Problems and Fixes
- Pattern does not appear in the inserter. The
TitleorSlugheader is missing, the slug is not unique, orInserter: nois set. Also check that the file is directly inpatterns/, not a subfolder. - "This block contains unexpected or invalid content" after inserting. The pattern's markup was hand-edited and no longer matches the block's save output. Rebuild the section in the editor and copy fresh markup.
- Images in the pattern are broken on other sites. The markup uses an absolute URL from the development site. Use
get_theme_file_uri()in theme patterns. - Theme patterns changed, but existing pages did not. That is expected. Patterns are copied into content on insert. Use a synced pattern or a template part for content that must stay in sync.
- Too many irrelevant patterns. Remove core patterns, disable remote patterns, and unregister ones you do not need.
Block Patterns FAQ
A regular block pattern is inserted as independent blocks, so later edits affect only that page. A synced pattern stays linked to its source, so editing it in one place updates every page that uses it.
Yes. Patterns are a block editor feature, so they work in the post editor on any theme. Classic themes can register patterns with register_block_pattern, and recent versions of WordPress also load PHP files from a patterns folder in classic themes.
No. When a pattern is inserted, its blocks are copied into the page. Changing the pattern file only affects future insertions. For content that must update everywhere, use a synced pattern or a template part.
Use the theme for patterns that are tied to its design and styles. Use a plugin for patterns that represent site content or company-wide components that should survive a theme change.
Yes. Directory patterns load in the inserter by default, and you can copy any pattern from wordpress.org/patterns and paste it into the editor. Block themes can also list directory pattern slugs in theme.json to include them.
Conclusion
Block patterns turn your best layouts into reusable building blocks. Editors get consistent, on-brand sections in two clicks, and you stop rebuilding the same hero and feature grid on every page. Create quick patterns in the editor for a single site, ship design-specific patterns as files in your theme's patterns/ folder, and register company-wide patterns from a plugin with register_block_pattern().
Organize them with categories and keywords, offer starter patterns for new pages, trim the core and remote patterns editors do not need, and always build the markup in the editor rather than by hand. Patterns pair naturally with a block theme built from scratch, where they become the main way editors assemble pages.
Here are some useful references for going deeper on block patterns:
- Theme Handbook: Patterns — registering patterns in themes and all supported header fields.
- Block Editor Handbook: Patterns API — register_block_pattern, categories, and unregistering patterns.
- WordPress Documentation: Patterns — creating and managing patterns in the editor.
- WordPress.org: Pattern Directory — community patterns you can copy into any site.
- Developer Reference: register_block_pattern() — function signature and arguments.


