Block patterns are one of the most powerful features in the WordPress block theme ecosystem. They are pre-built layouts made of blocks that you can insert with a single click — hero sections, pricing tables, testimonial grids, call-to-action bars, team member layouts, and anything else you can build with blocks. Instead of assembling the same layout manually every time, you build it once as a pattern and reuse it across your entire site.
WordPress ships with dozens of default patterns, but the real power comes from creating your own. Custom patterns let you define your brand’s specific layouts, enforce design consistency across your site, and give content editors pre-approved sections they can drop into any page without touching the design.
This guide covers everything: registering patterns in PHP, organizing them into categories, understanding synced vs unsynced patterns, creating patterns from the editor, and building advanced PHP-based dynamic patterns. If you are new to block themes, start with our complete theme.json configuration guide first.
What Block Patterns Are (and Are Not)
A block pattern is a collection of blocks arranged in a specific layout with predefined content, styles, and settings. When you insert a pattern into a page, WordPress copies all the blocks and their attributes into your content. From that point, you can edit the blocks individually — the pattern is just the starting point.
Patterns are not reusable blocks (now called synced patterns). The difference matters:
| Feature | Regular Pattern (Unsynced) | Synced Pattern |
|---|---|---|
| What happens on insert | Blocks are copied. Each instance is independent. | A reference is inserted. All instances share the same content. |
| Editing one instance | Only affects that instance | Changes appear everywhere the pattern is used |
| Best for | Starting layouts, templates, design systems | Shared content like CTAs, announcements, footer blocks |
| Stored as | PHP registration or wp_block post type | wp_block post type with wp_pattern_sync_status meta |
Method 1: Register Patterns in PHP
The most reliable way to add custom patterns to your block theme is through PHP registration using the register_block_pattern() function. This approach keeps patterns in your theme’s codebase, makes them version-controllable, and ensures they are available immediately on theme activation.
Basic Pattern Registration
add_action( 'init', function() {
register_block_pattern(
'mytheme/hero-with-cta',
array(
'title' => __( 'Hero Section with CTA', 'mytheme' ),
'description' => __( 'A full-width hero section with heading, paragraph, and two buttons.', 'mytheme' ),
'categories' => array( 'featured', 'banner' ),
'keywords' => array( 'hero', 'banner', 'cta', 'landing' ),
'content' => '
Build Something Beautiful
Create stunning websites with the power of WordPress block themes.
',
)
);
});
Pattern Properties Explained
| Property | Required | Purpose |
|---|---|---|
title | Yes | Display name in the pattern inserter |
content | Yes | Block markup (copy from the editor’s Code Editor view) |
description | No | Shown as a tooltip in the pattern inserter |
categories | No | Array of category slugs for organization |
keywords | No | Search terms to help users find the pattern |
viewportWidth | No | Preview width in pixels (default: 800) |
blockTypes | No | Suggest this pattern when specific blocks are inserted |
inserter | No | Set to false to hide from the inserter (for programmatic use only) |
Method 2: File-Based Patterns (WordPress 6.0+)
Since WordPress 6.0, you can register patterns by simply creating PHP files in your theme’s patterns/ directory. WordPress automatically discovers and registers them — no register_block_pattern() call needed.
Create the Pattern File
Create a file at patterns/hero-cta.php in your theme:
<?php
/**
* Title: Hero Section with CTA
* Slug: mytheme/hero-cta
* Categories: featured, banner
* Keywords: hero, banner, cta, landing
* Viewport Width: 1200
*/
?>
<!-- wp:cover {"dimRatio":60,"overlayColor":"black","isUserOverlayColor":true,"align":"full"} -->
<div class="wp-block-cover alignfull">
<span class="wp-block-cover__background has-black-background-color has-background-dim-60 has-background-dim"></span>
<div class="wp-block-cover__inner-container">
<!-- wp:heading {"textAlign":"center","level":1} -->
<h1 class="wp-block-heading has-text-align-center">Build Something Beautiful</h1>
<!-- /wp:heading -->
<!-- wp:paragraph {"align":"center"} -->
<p class="has-text-align-center">Create stunning websites with WordPress block themes.</p>
<!-- /wp:paragraph -->
</div>
</div>
<!-- /wp:cover -->
The PHP comment block at the top is the pattern header. WordPress reads these comments to register the pattern automatically. The Slug must be unique and should follow the themename/pattern-name convention.
This method is cleaner than PHP registration for most use cases. Your pattern content lives in its own file, it is easy to read and edit, and you do not need any registration code.
Creating Pattern Categories
Custom categories help organize your patterns in the inserter. Register them using register_block_pattern_category():
add_action( 'init', function() {
register_block_pattern_category(
'mytheme-heroes',
array(
'label' => __( 'Hero Sections', 'mytheme' ),
)
);
register_block_pattern_category(
'mytheme-testimonials',
array(
'label' => __( 'Testimonials', 'mytheme' ),
)
);
register_block_pattern_category(
'mytheme-pricing',
array(
'label' => __( 'Pricing Tables', 'mytheme' ),
)
);
});
Then assign patterns to these categories using the categories property in either the PHP registration or the file header comment.
How to Get Block Markup for Patterns
The hardest part of creating patterns is getting the correct block markup. Here is the most reliable workflow:
- Design the layout visually in the WordPress block editor. Add blocks, adjust settings, apply colors, set spacing — everything you want in the pattern
- Switch to the Code Editor by clicking the three-dot menu in the top-right corner of the editor and selecting “Code editor”
- Copy the entire block markup — this is what goes into the
contentproperty of your pattern - Paste it into your pattern file (either the PHP registration or the
patterns/file) - Replace specific content with placeholders — change “Our Company” to “Your Heading Here” so editors know what to customize
This visual-first approach ensures your block markup is always valid. Writing block comments by hand is error-prone and unnecessary when the editor generates correct markup for you.
Synced Patterns: Shared Content Across Your Site
Synced patterns (formerly called reusable blocks) are different from regular patterns. When you edit a synced pattern, the changes appear everywhere that pattern is used. This is ideal for content that needs to stay consistent across your site:
- Call-to-action banners that appear on multiple pages
- Announcement bars for promotions or events
- Standard disclaimers or legal notices
- Team bios or company info blocks used in footers and about pages
Creating Synced Patterns
In the editor, select one or more blocks, click the three-dot menu, and choose “Create pattern”. Toggle the “Synced” option to create a synced pattern. Give it a descriptive name and assign a category.
Synced patterns are stored as wp_block posts in the database. You can manage them from Appearance > Editor > Patterns in the WordPress admin. From there you can edit, duplicate, or delete synced patterns.
Advanced: Dynamic Patterns with PHP
Because file-based patterns are PHP files, you can use PHP logic to create dynamic patterns. This is powerful for patterns that need to pull data from WordPress:
<?php
/**
* Title: Latest Posts Grid
* Slug: mytheme/latest-posts-grid
* Categories: posts
*/
$recent_posts = get_posts( array(
'numberposts' => 3,
'post_status' => 'publish',
) );
if ( empty( $recent_posts ) ) {
return;
}
?>
<!-- wp:group {"align":"wide","layout":{"type":"constrained"}} -->
<div class="wp-block-group alignwide">
<!-- wp:heading -->
<h2 class="wp-block-heading">Latest from Our Blog</h2>
<!-- /wp:heading -->
<!-- wp:columns -->
<div class="wp-block-columns">
<?php foreach ( $recent_posts as $post ) : ?>
<!-- wp:column -->
<div class="wp-block-column">
<!-- wp:heading {"level":3} -->
<h3 class="wp-block-heading"><?php echo esc_html( $post->post_title ); ?></h3>
<!-- /wp:heading -->
<!-- wp:paragraph -->
<p><?php echo esc_html( wp_trim_words( $post->post_content, 20 ) ); ?></p>
<!-- /wp:paragraph -->
</div>
<!-- /wp:column -->
<?php endforeach; ?>
</div>
<!-- /wp:columns -->
</div>
<!-- /wp:group -->
Use dynamic patterns carefully. The PHP executes when the pattern is inserted, not on every page load. Once the blocks are in the content, they become static. For truly dynamic content, use the Query Loop block or custom dynamic blocks instead.
Using theme.json to Style Your Patterns
Your patterns inherit styles from theme.json. This means colors, typography, spacing, and layout settings defined in your theme’s global styles automatically apply to pattern blocks. To make your patterns look consistent with the rest of your theme:
- Use preset colors (like
has-primary-color) instead of hardcoded hex values - Use preset font sizes (like
has-large-font-size) instead of pixel values - Use spacing presets from your theme’s spacing scale instead of fixed padding and margin values
This approach ensures that when someone changes the primary color in the Site Editor’s global styles, your patterns update automatically. Hardcoded values create patterns that look out of place when the theme styles change.
Pattern Best Practices
- Use descriptive names and keywords so editors can find patterns quickly in the inserter
- Set appropriate
viewportWidthfor each pattern so the preview in the inserter accurately represents the layout - Include placeholder content that makes it obvious what editors should replace (“Your Heading Here” instead of “Lorem Ipsum”)
- Group related blocks inside a Group or Cover block so the entire pattern can be moved or deleted as one unit
- Test patterns at multiple screen sizes — a pattern that looks great on desktop but breaks on mobile is not ready for production
- Use the
patterns/directory for file-based patterns whenever possible — it is cleaner thanregister_block_pattern()calls in PHP - Prefer theme.json presets over hardcoded values for colors, fonts, and spacing so patterns adapt to style changes
For deeper control over how patterns look, our guide on configuring global styles in theme.json covers the styles section, element-level styling, and CSS custom properties that your patterns inherit. Block patterns are the bridge between a design system and the content editing experience. They give developers control over approved layouts while giving editors the freedom to customize content. Start with a few essential patterns — a hero section, a CTA bar, and a feature grid — and expand your library as your theme matures.
