A blank editor is not always a useful starting point for a client. Often the person publishing a page already knows the kind of section they need: an introduction, a short service description or a heading followed by a call to action.
I want those sections to have a considered starting layout without turning every small content change into a development request. Registered block patterns are useful here. They let me package ordinary blocks into something recognisable, while leaving the inserted content available in the editor.
In this tutorial: What we are building; Before you start; 1. Register a category and a pattern; 2. Give the section a small styling boundary; 3. Understand what happens after insertion; Check the behaviour.
What we are building
An introductory section made from a Group, Heading and Paragraph. It appears in a custom pattern category and can be inserted more than once. This is an ordinary, unsynchronised starting pattern, not a custom block with its own editor interface.
Before you start
Pattern registration has been available since WordPress 5.5. Put presentation patterns in the theme that owns their design. If a reusable feature must survive a theme switch, think separately about whether its content model belongs in a plugin.
Start by arranging the section in Gutenberg and checking the editor's code view. That is a useful way to get valid native block markup rather than guessing at the saved structure.
1. Register a category and a pattern
add_action('init', function () {
register_block_pattern_category('cn-sections', [
'label' => __('Page sections', 'my-theme'),
]);
register_block_pattern('my-theme/intro', [
'title' => __('Simple introduction', 'my-theme'),
'description' => __('A heading and a short introduction.', 'my-theme'),
'categories' => ['cn-sections'],
'content' => '<!-- wp:group {"className":"intro-section"} -->'
. '<div class="wp-block-group intro-section">'
. '<!-- wp:heading -->'
. '<h2 class="wp-block-heading">A useful introduction</h2>'
. '<!-- /wp:heading -->'
. '<!-- wp:paragraph -->'
. '<p>Explain what this page helps someone do.</p>'
. '<!-- /wp:paragraph -->'
. '</div><!-- /wp:group -->',
]);
});
Replace the text domain with the theme's own domain. The pattern name includes a namespace so it does not collide with another theme or plugin's registration. The visible title should help an editor recognise the section, rather than describe the PHP that registers it.
For a larger section I would keep the markup in a separate, carefully reviewed file. The important boundary is that registration supplies block content; it is not a reason to build a second rendering system around ordinary paragraphs.
2. Give the section a small styling boundary
.intro-section {
max-width: 42rem;
margin-inline: auto;
padding-block: 2rem;
}
A class on the outer Group gives the section a clear styling boundary. Keep that class in the inserted markup and make the stylesheet available in both the frontend and editor where appropriate.
The class does not automatically load an optional stylesheet. That requires a deliberate asset-loading approach in the theme. A registered pattern and a conditional CSS loader solve different parts of the problem.
3. Understand what happens after insertion
Once an ordinary pattern is inserted, its blocks become part of that page's content. An editor can replace the heading, lengthen the paragraph or remove the section. Changing the registration later does not automatically rewrite every earlier insertion.
That independence is often exactly what I want. It also means I should not promise a client that updating a pattern file will update all their existing pages. Shared content needs a separately chosen reusable or synchronised mechanism.
Check the behaviour
Insert the pattern into a draft page, change its text, save and reopen it. There should be no invalid-block recovery prompt. Check the editor and frontend at a narrow width, including a long heading and more copy than the initial example contains.
Insert it twice and make sure there are no repeated HTML IDs. Check the heading levels in the page as a whole. A neatly packaged section can still create a confusing outline if every heading is chosen in isolation.
For me, the value is giving someone a sensible place to start. A pattern should remove repetitive assembly while leaving the content understandable and genuinely editable.
References
The WordPress references for register_block_pattern and register_block_pattern_category describe the registration API.