How to Create Custom Block Patterns in WordPress Block Themes

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:

FeatureRegular Pattern (Unsynced)Synced Pattern
What happens on insertBlocks are copied. Each instance is independent.A reference is inserted. All instances share the same content.
Editing one instanceOnly affects that instanceChanges appear everywhere the pattern is used
Best forStarting layouts, templates, design systemsShared content like CTAs, announcements, footer blocks
Stored asPHP registration or wp_block post typewp_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

PropertyRequiredPurpose
titleYesDisplay name in the pattern inserter
contentYesBlock markup (copy from the editor’s Code Editor view)
descriptionNoShown as a tooltip in the pattern inserter
categoriesNoArray of category slugs for organization
keywordsNoSearch terms to help users find the pattern
viewportWidthNoPreview width in pixels (default: 800)
blockTypesNoSuggest this pattern when specific blocks are inserted
inserterNoSet 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:

  1. Design the layout visually in the WordPress block editor. Add blocks, adjust settings, apply colors, set spacing — everything you want in the pattern
  2. Switch to the Code Editor by clicking the three-dot menu in the top-right corner of the editor and selecting “Code editor”
  3. Copy the entire block markup — this is what goes into the content property of your pattern
  4. Paste it into your pattern file (either the PHP registration or the patterns/ file)
  5. 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 viewportWidth for 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 than register_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.

Scroll to Top