Block patterns are one of the most underused features in modern WordPress development. They let you define reusable sections of Gutenberg content – headers, pricing tables, testimonial layouts, feature grids – and make them available across your entire site with a few clicks. For developers building client sites or themes, block patterns are the answer to the “how do I give clients reusable page components without a page builder?” question. This guide covers everything from registering your first pattern to organizing them into categories, making them translatable, and building a proper pattern library for your projects.
What Are Block Patterns and Why They Matter
A block pattern is a pre-designed collection of blocks that can be inserted into the editor in one click. WordPress ships with a set of core patterns, but the real power comes when you register custom patterns tailored to your theme or client’s brand.
The difference between patterns and reusable blocks (now called “synced patterns” in WordPress 6.x) is important. Synced patterns are linked instances – edit one and all instances update. Regular block patterns are templates – each insertion creates an independent copy that editors can modify freely. For layout templates and starting-point sections, non-synced patterns are usually what you want.
- Theme patterns – Registered by your theme, available on any site using the theme
- Plugin patterns – Registered by a plugin, available whenever the plugin is active
- Core patterns – Shipped with WordPress core, always available
- Remote patterns – From the WordPress.org pattern directory, available in the editor’s pattern inserter
For client work, you almost always want theme patterns or plugin patterns – content you define and control, not random community patterns your client might accidentally insert.
Registering Block Patterns with PHP
Block patterns are registered with the register_block_pattern() function. The registration happens on the init hook. The function takes a pattern name (namespaced slug) and an array of arguments.
Basic Pattern Registration
The pattern name must be namespaced – use your theme or plugin slug as the prefix, followed by a descriptive name. Avoid generic names that might conflict with other plugins or core patterns.
Pattern Arguments Breakdown
| Argument | Type | Description | Required |
|---|---|---|---|
| title | string | Human-readable name shown in the inserter | Yes |
| content | string | The block markup (HTML with block comments) | Yes |
| description | string | Accessible description for screen readers | No |
| categories | array | Pattern category slugs to appear in | No |
| keywords | array | Search keywords for the inserter | No |
| viewportWidth | int | Width for pattern preview rendering | No |
| blockTypes | array | Block types this pattern is relevant to | No |
| postTypes | array | Post types where this pattern appears | No |
| inserter | bool | Show in inserter UI (default: true) | No |
| source | string | Pattern source identifier | No |
Writing the Pattern Markup
The content argument takes Gutenberg block markup – the same HTML comment format you see when you copy blocks from the editor. Writing this by hand is tedious. The practical approach is to build the pattern visually in the editor, then copy the block markup from the Code Editor view.
Getting Block Markup from the Editor
- Open any post or page in the WordPress editor
- Build your pattern layout visually using blocks
- Click the three-dot menu in the top toolbar and select “Code editor”
- Copy the HTML – this is your pattern content
- Paste it into your PHP registration as the
contentvalue
A Real-World Hero Section Pattern
Storing Pattern Content in Separate Files
Embedding long block markup strings in PHP registration calls gets messy fast. A cleaner approach is storing each pattern’s markup in a separate .html file and loading it with file_get_contents(). This keeps your registration code clean and makes patterns easier to edit visually.
This pattern (the PHP pattern, not the block pattern) is how many professional themes organize their pattern libraries. Create a patterns/ directory in your theme, store each pattern as a .html file, and loop through them to register all at once.
Block Theme Pattern Registration (theme.json + patterns/ folder)
Block themes (Full Site Editing themes) have an even simpler pattern registration method. If you’re new to block themes, our guide on migrating from a classic theme to a block theme covers the full transition process. WordPress automatically registers any .html file placed in the theme’s patterns/ directory. No PHP registration code needed.
Pattern File Headers
Block theme patterns use file headers (similar to plugin file headers) to declare their metadata. Place these as an HTML comment at the top of the .html file.
WordPress reads these headers and registers the pattern automatically on every page load. This is the recommended approach for block themes and removes the need for any PHP registration code.
Available Header Fields
- Title (required) – Display name in the inserter
- Slug (required) – Unique identifier, namespaced to theme (e.g.,
mytheme/hero-section) - Description – Accessible description
- Viewport Width – Preview width in pixels
- Categories – Comma-separated list of category slugs
- Keywords – Comma-separated search terms
- Block Types – Block types this pattern is suggested for
- Post Types – Post types where pattern appears
- Inserter – true/false, whether to show in inserter
- Template Types – Template types (page, post, etc.) this pattern suits
Creating and Registering Custom Pattern Categories
WordPress ships with several default pattern categories (featured, posts, text, gallery, call-to-action, team, testimonials, services, portfolio, media). For an overview of how the full FSE architecture fits together, check out our guide to dynamic content layouts in FSE., call-to-action, team, testimonials, services, portfolio, media. For client themes or plugins with many patterns, you’ll want to add your own categories to keep things organized.
Custom categories appear in the pattern inserter’s sidebar, giving editors a clear way to browse patterns by purpose. For a client site, categories like “Client Brand”, “Product Pages”, and “Blog Layouts” make sense. For a multipurpose theme, broader categories like “Hero Sections”, “Feature Sections”, and “Footer Layouts” work better.
Assigning Patterns to Multiple Categories
A pattern can belong to multiple categories. The categories argument accepts an array of category slugs. This is useful for patterns that serve multiple purposes – a “stats with CTA” pattern might belong to both the “call-to-action” and “about” categories.
Making Block Patterns Translatable
Patterns with hardcoded text strings create a translation problem – the text is embedded in block markup, not in PHP where __() functions work normally. WordPress 6.0+ added proper support for translatable patterns, but the implementation requires care.
Method 1: PHP Pattern Registration with Translation Functions
When registering patterns via PHP, you can use translation functions inside the content string. This works because the content is a PHP string being evaluated, not a static HTML file.
The key is using esc_html__() for text that gets displayed in block markup. The translation function runs when the pattern content is generated, so translators can properly localize the pattern text.
Method 2: Block Theme Patterns with wp:pattern translate Attribute
For block themes using HTML pattern files, WordPress 6.0 introduced a translation mechanism. Text wrapped in specific block attributes can be marked for translation. This works with the block theme’s translation loading and the standard WordPress i18n toolchain.
WP-CLI Pattern String Extraction
WP-CLI’s i18n make-pot command can extract translatable strings from pattern files when you pass the --include flag to include your patterns directory. This populates your POT file with pattern strings for translators.
Disabling Core and Remote Patterns
By default, WordPress shows core patterns and patterns from the WordPress.org pattern directory in the inserter. For client sites, this creates noise – clients see hundreds of generic patterns alongside your carefully designed custom ones. You’ll often want to disable the remote pattern directory and selectively remove core patterns.
The should_load_remote_block_patterns filter controls the remote directory. Set it to false and the inserter only shows patterns registered locally. For core patterns, unregister_block_pattern() lets you remove specific ones by name.
Building a Pattern Library for Client Projects
For agencies or developers who build multiple client sites, a pattern library plugin is worth the investment. Instead of registering patterns in each theme, you build a plugin that contains all your standard layouts and activate it on client sites.
Pattern Library Plugin Structure
Organize patterns by type, load them all from the main plugin file, and version your pattern library. When you update a pattern design, you update the plugin, and all client sites get the updated patterns on next activation check.
Conditional Pattern Loading
Not all patterns are relevant to all post types or templates. Use the postTypes argument to restrict where patterns appear, and add post-type checks in your registration loop to avoid loading patterns that don’t make sense in a given context.
Pattern Previews and viewportWidth
The viewportWidth argument controls how wide the editor renders the pattern preview in the inserter panel. Getting this right makes your patterns look good in the preview thumbnail, which matters for client usability.
- Full-width layouts – Use 1280 or 1440 (matches desktop breakpoints)
- Container-width layouts – Use 1200 (standard container width)
- Narrow content patterns – Use 800-900 (matches content column width)
- Card/widget patterns – Use 400-600 (matches sidebar or card width)
The editor scales the preview to fit the inserter panel, so these values affect proportion rather than absolute size. Match the viewport width to the context where the pattern is designed to be used.
Common Mistakes to Avoid
- Hardcoded image IDs – Never put media library image IDs in pattern markup. They won’t exist on other sites. Use placeholder images from your theme’s assets or leave image blocks empty for editors to fill in.
- Absolute URLs – Avoid absolute URLs in patterns. Use
get_theme_file_uri()or relative paths where possible. Absolute URLs break when patterns are used on different domains. - Non-namespaced pattern names – Always namespace.
hero-sectionwill conflict.mytheme/hero-sectionwon’t. - Missing closing block comments – Every opening block comment (
<!-- wp:heading -->) needs a closing comment (<!-- /wp:heading -->). Missing closers cause block validation errors in the editor. - Inline styles that conflict with themes – Patterns with heavy inline styling become unmaintainable and look wrong on sites with different color schemes. Use theme.json color palette values and spacing scale instead of hardcoded hex values.
Testing Your Patterns
Always test patterns in a clean WordPress install, not just the site where you built them. Pattern issues that are invisible in the source environment become obvious elsewhere:
- Patterns that reference local image IDs that don’t exist on other sites
- Block validation errors from slightly malformed markup
- Patterns that look wrong without theme-specific CSS
- Missing block type registrations (custom blocks in patterns require the block plugin to be active)
The WordPress theme unit test framework includes a pattern checker. Use it before distributing patterns in a theme submitted to the WordPress.org directory.
Patterns vs Template Parts vs Reusable Blocks
The terminology confusion around patterns, template parts, and reusable/synced blocks trips up a lot of developers. Here’s the clear breakdown:
| Feature | Block Pattern | Template Part | Synced Pattern (Reusable Block) |
|---|---|---|---|
| Sync behavior | Not synced – copies are independent | Synced across all uses | Synced – edit once, updates everywhere |
| Use case | Layout starting points | Site structure (header, footer) | Repeated content that must stay consistent |
| Editor access | Inserter patterns panel | Template editor | Patterns panel (synced tab) |
| Registration | PHP or HTML file | theme.json or HTML file | Via WordPress editor UI |
| Client editable | Yes, freely | Via Site Editor | Yes, but changes affect all instances |
For most page section layouts that clients customize per page, non-synced block patterns are the right tool. For content that must stay consistent across the site (like a “Book a Demo” CTA section used on many pages), synced patterns are better.
Build Better WordPress Sites with Block Themes
Block patterns are a cornerstone of modern WordPress development. Brndle covers block themes, FSE, and Gutenberg development in depth. For more on building with the block editor, see our block themes guides and our deep-dives on Full Site Editing workflows for client projects.
