When you ship a block theme with dozens of patterns, the pattern inserter can quickly become overwhelming. Editors scroll through an unordered list of every pattern in the library trying to find the right layout for their page, and usually give up before finding it. The fix is straightforward: block pattern categories. Used correctly, they turn your pattern library into a curated, searchable catalog that guides editors directly to what they need.
This guide covers everything a theme developer needs to know about block pattern categories in WordPress, from registering your own categories to cleaning out the default ones, from organizing patterns by purpose to controlling which remote patterns load from the WordPress.org Pattern Directory. By the end, you will have a pattern library that is easy to navigate and reflects your theme’s design system. If you have not yet built patterns for your theme, start with how to create custom block patterns in WordPress first.

What Are Block Pattern Categories?
Block pattern categories are grouping labels that appear as filter tabs in the Block Inserter’s Patterns panel and in the Pattern modal (accessed from any page or post). When an editor clicks the Patterns button in the inserter, they see a list of categories on the left. Clicking a category filters the pattern grid to show only matching patterns.
Without categories, all patterns appear in a flat “All” view. With well-named categories, editors can jump directly to “Hero Sections” or “Pricing Tables” without scrolling through layouts meant for an entirely different purpose. This small UX improvement has a measurable effect on how confidently non-technical editors use block themes.
Technically, a category is just a string slug paired with a label. There is no taxonomy database involved, categories exist only in memory, registered via the PHP API during the init hook. A pattern can belong to multiple categories simultaneously.
The Default WordPress Pattern Categories
WordPress ships with a set of built-in pattern categories. As of WordPress 6.5 these include: featured, posts, text, gallery, call-to-action, banner, header, footer, query, team, and testimonials.
These categories serve core patterns and remote patterns pulled from the Pattern Directory. The problem is that they may not map well to your theme’s design system. If your theme calls what WordPress calls a “banner” a “hero section,” editors will look in one place and find patterns in another. The mismatch creates confusion.
You have three options: keep the defaults and assign your patterns to them, keep some and remove others, or remove all defaults and build your own category taxonomy from scratch. The right choice depends on how much control you need over the editor experience.
Registering Custom Block Pattern Categories
The WordPress function register_block_pattern_category() accepts a slug and an array of arguments. The slug is what you use when assigning patterns to categories. The label is the human-readable string shown in the inserter. An optional description provides context for screen readers and internal documentation.
Run registration on the init hook at the default priority (10). Core registers its own categories at priority 9, so you can safely run after that without conflicts.
A few naming conventions worth noting. Prefixing your category slugs with your theme slug (e.g., mytheme/hero) prevents collisions with core categories and third-party plugins. WordPress accepts any string as a slug, but a namespace/name pattern is the emerging convention and aligns with how block names and pattern slugs work elsewhere in the platform.
Keep label strings short, two or three words maximum. These appear as tab labels in a narrow sidebar and truncate if they are too long. “Hero Sections” is better than “Full-Width Hero and Banner Sections.”
Assigning Patterns to Categories
Once you have registered your categories, you assign patterns to them via the categories key in the pattern registration array. This key accepts an array of category slugs. A single pattern can belong to multiple categories, a “split hero” pattern might belong to both mytheme/hero and mytheme/landing-page.
Notice that the categories value references the slug you registered earlier (mytheme/hero), not the label. If you reference a slug that has not been registered, the pattern simply will not appear under that category, it will still exist in “All” but will be unfiltered. This makes it easy to catch typos: if a pattern disappears from a category, the slug likely has a mismatch.
The keywords array is separate from categories but works alongside them. Keywords improve the search experience within the inserter. A user who types “banner” in the search field will find your hero pattern if “banner” is in its keyword list, even if the category is named something different. Use keywords for synonyms and alternate names.
Organizing Patterns by Purpose
The most effective category structures organize patterns by their purpose on the page, what job they do for the editor, rather than by their visual style. Style is subjective and changes with design trends. Purpose is stable: a testimonial section will always be a testimonial section, regardless of whether it uses a card grid or a carousel this year.
Here is a category structure that works well for most marketing-focused block themes:
- Hero Sections (
mytheme/hero), Full-width introductory sections typically placed at the top of landing pages. Includes centered, split, and minimal variants. - Features (
mytheme/features), Grid or list layouts that highlight product or service capabilities. - Call to Action (
mytheme/cta), Conversion-focused sections with prominent buttons. Includes inline CTAs, full-width banners, and popup-style blocks. - Testimonials (
mytheme/testimonials), Quote-based social proof sections. Carousel, card grid, and single-quote variants. - Pricing (
mytheme/pricing), Pricing table layouts for one, two, or three tiers. - Team (
mytheme/team), Staff and team member profile layouts. - FAQ (
mytheme/faq), Accordion and list-based frequently asked questions sections. - Stats & Numbers (
mytheme/stats), Large-number highlight sections for metrics and achievements. - Blog & Posts (
mytheme/blog), Query Loop-based patterns for post archives, latest posts, and featured articles. - Page Templates (
mytheme/pages), Full-page layouts combining multiple sections. These go in the Patterns tab when users create new pages.
This structure covers the most common page-building scenarios without creating so many categories that the filter list itself becomes unwieldy. Aim for 8–12 categories. Fewer than 6 and categorization adds little value; more than 15 and editors spend more time choosing a category than finding the pattern.
Removing Default Pattern Categories
When you build your own category structure, the default core categories add noise. An editor sees both “Call to Action” (your category) and “call-to-action” (core’s category) and wonders why there are two. The solution is to unregister the core categories you do not need.
The function is unregister_block_pattern_category() and it accepts a single slug. Call it at priority 20 on init so core has already registered its categories before you remove them.
A word of caution: do not remove core categories that you actively use for your own patterns. If you remove testimonials and you have patterns assigned to it, those patterns will appear only under “All.” Remove a category only when you have replaced it with a namespaced equivalent or when no patterns in your theme use that slug.
Also note that removing a category does not remove the patterns assigned to it. Patterns assigned to an unregistered category appear only in the “All” view. If you want to fully hide a pattern from editors, you would need to unregister the pattern itself, but that is a different operation with different implications for existing content.
Registering Patterns via the /patterns/ Directory
Since WordPress 6.0, block themes can register patterns by dropping PHP files in a patterns/ directory at the root of the theme. WordPress auto-discovers and registers these files without any additional PHP code. The file headers serve as the registration metadata.
To assign a patterns-directory pattern to a custom category, include the category slug in the Categories file header. The header uses comma-separated slugs for multiple categories.
The patterns directory approach has a significant advantage for theme development: it keeps pattern markup out of functions.php. Each pattern lives in its own file, making the theme easier to maintain and search. A developer looking for the hero pattern opens patterns/hero-split.php rather than scanning hundreds of lines of functions.php for a register_block_pattern() call. This file-based structure also integrates cleanly with the design system approach in theme.json where tokens and global styles drive visual consistency across all patterns.
One important note: the category slugs referenced in pattern file headers must still be registered via PHP before they can be used as filter tabs. The patterns/ directory handles pattern content discovery, but category registration still happens in functions.php (or an included file). If you reference a category slug in a pattern header before registering it, the pattern will appear under “All” but not in the category filter.
Controlling Remote Patterns from the Pattern Directory
By default, WordPress fetches patterns from the WordPress.org Pattern Directory and surfaces them in the inserter. For some themes this is a feature, it gives editors access to a huge library without any extra work. For others it is a liability: remote patterns use arbitrary category slugs, may not match your design system, and add network requests to every editor page load.
You have several options for controlling remote pattern loading:
The cleanest option for block themes is the theme.json approach. Setting "patterns": [] under "settings" tells WordPress not to load any remote patterns for this theme. This is a theme-level declaration that sits in version control and requires no PHP. It is the approach recommended by the Gutenberg team for themes that want a fully controlled pattern library.
The PHP filter approach (should_load_remote_block_patterns) is useful when you want to suppress remote patterns on a site level regardless of what the active theme declares. It is also the only option in classic themes.
Using theme.json to Declare Pattern Categories
As of WordPress 6.5, theme.json gained a patterns array under settings. This array accepts pattern slugs from the WordPress.org Pattern Directory, not custom category registrations. But the two systems work together: you use theme.json to curate which remote patterns load, and PHP to define the categories those patterns (and your own) appear under.
Here is an example theme.json configuration that disables remote patterns entirely and relies on the theme’s own patterns directory:
{
"$schema": "https://schemas.wp.org/trunk/theme.json",
"version": 3,
"settings": {
"patterns": []
}
}
For most custom themes this is the right default. You start with a clean slate and add only the patterns your theme ships with. Editors see only patterns that match your design system.
Pattern Category Discovery in the Editor UI
Understanding how editors actually encounter your categories helps you design the hierarchy correctly. There are three places pattern categories appear in the WordPress editor:
The Block Inserter (+ button). When an editor opens the inserter and clicks the “Patterns” tab, they see your categories listed in a left sidebar. The default view shows all patterns. Clicking a category filters the grid. This is the primary discovery path for patterns that get inserted inline into existing page content.
The Pattern Chooser modal. When an editor creates a new page or post and the blank canvas state is shown, WordPress may offer a pattern chooser modal. This modal also groups patterns by category. Categories with a large number of patterns display more prominently here.
Template editing in the Site Editor. When editing templates in the Site Editor, the inserter shows patterns filtered to types that make sense at the template level (header, footer, general layouts). The same categories apply here.
Knowing this, “Page Templates” as a category is especially valuable: editors looking to start a full page from scratch will check that category first. Hero sections, CTAs, and FAQ sections are more likely to be inserted partway through page building.
Multi-Category Patterns: When and Why
Assigning a pattern to multiple categories is powerful but can be overused. The right use case is a pattern that genuinely serves two distinct purposes depending on context. A “3-column features with CTA” pattern makes sense in both mytheme/features and mytheme/cta, an editor building a features section would find it in the first category; an editor looking for a soft CTA would find it in the second.
Avoid assigning every pattern to a catch-all category. Some theme developers add all patterns to a mytheme/all category “so editors can always find them.” This defeats the purpose of categorization, editors will default to the catch-all category and ignore the more specific ones.
A good rule of thumb: assign each pattern to a maximum of two categories. If you cannot identify two genuine use cases, assign it to one. Multi-category assignments should reflect actual editor behavior, not a fallback for discoverability.
A Real-World Example: Complete Pattern Library Structure
Here is how a complete block theme pattern library might be organized, from the category registration in functions.php to the patterns/ directory layout and the final inserter appearance.
Category registration (functions.php):
add_action( 'init', function(): void {
$categories = array(
'mytheme/hero' => __( 'Hero Sections', 'mytheme' ),
'mytheme/features' => __( 'Features', 'mytheme' ),
'mytheme/cta' => __( 'Call to Action', 'mytheme' ),
'mytheme/testimonials' => __( 'Testimonials', 'mytheme' ),
'mytheme/pricing' => __( 'Pricing', 'mytheme' ),
'mytheme/faq' => __( 'FAQ', 'mytheme' ),
'mytheme/team' => __( 'Team', 'mytheme' ),
'mytheme/blog' => __( 'Blog', 'mytheme' ),
'mytheme/pages' => __( 'Page Templates', 'mytheme' ),
);
foreach ( $categories as $slug => $label ) {
register_block_pattern_category( $slug, array( 'label' => $label ) );
}
}, 10 );
// Remove overlapping core categories at priority 20.
add_action( 'init', function(): void {
foreach ( array( 'featured', 'banner', 'call-to-action', 'team', 'testimonials' ) as $slug ) {
unregister_block_pattern_category( $slug );
}
}, 20 );
patterns/ directory layout:
patterns/
├── hero/
│ ├── hero-centered.php # Categories: mytheme/hero
│ ├── hero-split.php # Categories: mytheme/hero
│ └── hero-minimal.php # Categories: mytheme/hero
├── cta/
│ ├── cta-full-width.php # Categories: mytheme/cta
│ └── cta-inline.php # Categories: mytheme/cta
├── features/
│ ├── features-3col-icons.php # Categories: mytheme/features
│ └── features-alternating.php # Categories: mytheme/features
├── testimonials/
│ ├── testimonials-grid.php # Categories: mytheme/testimonials
│ └── testimonials-single.php # Categories: mytheme/testimonials
├── pricing/
│ └── pricing-3tier.php # Categories: mytheme/pricing
└── pages/
├── page-landing.php # Categories: mytheme/pages
└── page-about.php # Categories: mytheme/pages, mytheme/team
With this structure, a developer onboarding to the theme can immediately understand the pattern library from the directory layout alone. An editor using the inserter sees nine clear categories, each with 2–4 focused patterns, and can find the right layout in seconds.
Best Practices for Pattern Category Naming
A few naming principles that hold up well across different project types:
Use noun phrases, not verbs. “Testimonials” is clearer than “Show Testimonials” or “Display Quotes.” Editors scan category names as labels, not instructions.
Match your site’s vocabulary. If the marketing team calls them “social proof sections,” name the category “Social Proof,” not “Testimonials.” The editor UI should use the same language as the rest of the project.
Avoid vague categories. A category named “General” or “Misc” is a symptom of a pattern that does not have a clear purpose. If you cannot categorize a pattern clearly, reconsider whether the pattern needs to exist or needs to be split into more focused variants.
Keep slugs stable. Once you publish a theme with registered category slugs, changing them requires also updating every pattern that references the old slug. Rename categories at their label level (user-facing string), but keep the slug unchanged unless you are making a major breaking version.
Test the inserter with a non-developer. Have someone who did not build the theme try to find a specific pattern using only the inserter. If they open “All” first and scroll, your category structure is not intuitive enough. Categories that go unused are categories that need to be renamed or merged.
Common Mistakes and How to Fix Them
Patterns not appearing in a category. The most common cause is a slug typo. The slug in the pattern’s categories array must exactly match the slug passed to register_block_pattern_category(). Check for trailing spaces, case differences, and namespace separators (use /, not -).
Unregistering a core category breaks Remote patterns. If a remote pattern from WordPress.org was assigned to testimonials and you unregister that category, the remote pattern disappears from the filter. This is expected behavior, but it can surprise developers who expected remote patterns to auto-reassign. If you want to keep remote patterns while renaming the category, register your replacement category with the same slug as the core category you are replacing.
Category registration order issues. If you use a patterns/ directory and register categories in a separate functions.php call, ensure the category registration runs on init at the same or earlier priority than WordPress’s auto-discovery of pattern files (which also runs on init). Priority 10 for categories and the default auto-discovery timing both work correctly together.
Too many categories for a small pattern library. A theme with 12 patterns and 10 categories leaves most categories empty or with a single pattern. The overhead of clicking a category tab to see one pattern is worse than just scrolling through 12 patterns in the “All” view. Add categories proportionally: each category should have at least 2–3 patterns to justify its existence in the filter list.
Block Patterns and the Site Editor: Category Considerations for Template Parts
Template parts, headers, footers, sidebars, are distinct from patterns in the WordPress data model, but they appear alongside patterns in some views of the Site Editor. As of WordPress 6.5, there is no category system for template parts equivalent to the one for patterns. They are organized by type (header, footer, general).
Where this affects your category strategy: if your theme ships “header” patterns (full-width block layouts intended to replace the header template part), these belong in a header category, either core’s or your own namespaced version. Do not confuse header patterns with the header template part. They serve different purposes: a header template part is a structural file that defines the header for all pages; a header pattern is a block arrangement an editor can insert on a specific page.
For most themes, it is safer to avoid shipping header and footer patterns unless they are explicitly branded as “page section” variants. Editors sometimes insert what they think is a header template replacement, then find the actual header template unchanged. Clear category names like “Page Headers” instead of “Headers” reduce this confusion.
Internationalization: Translatable Category Labels
Category labels pass through __( 'Label', 'textdomain' ) just like any other user-facing string in a theme. This is easy to overlook when registering categories programmatically. Every label in the array passed to register_block_pattern_category() should be wrapped in a translation function.
The slug itself is never translated, it is an internal identifier. Only the label and description keys in the arguments array need translation functions. If you are building a theme for a multilingual audience, double-check that the categories registration call does not use bare strings.
There is no equivalent of a translatable slug. If you need category labels to change based on locale, register multiple categories with locale-appropriate slugs, but this is an edge case that rarely comes up in practice.
Testing Your Category Setup
After setting up pattern categories, run through this checklist in a local environment before shipping:
- Open the Block Inserter on a new page or post. Click “Patterns.” Verify your category tabs appear in the left sidebar.
- Click each category tab. Verify only the intended patterns appear. Check for patterns missing from their expected category (slug typo) or appearing in the wrong category (wrong slug reference).
- Open the “All” view. Verify no orphaned patterns appear that are not assigned to at least one category.
- Search for pattern names and keywords. Verify that keyword-based search surfaces relevant patterns across categories.
- Check that removed core categories no longer appear as filter tabs.
- Verify that remote patterns from the Pattern Directory are or are not appearing, depending on your
theme.jsonconfiguration. - Test in the Site Editor (Appearance → Editor). Open the inserter and confirm categories appear there as well.
- If internationalization matters, switch the site language in Settings → General and verify category labels update in the inserter.
Wrapping Up
Block pattern categories are a small feature with a large impact on editor usability. A well-organized category structure turns a pattern library from a list of layouts into a curated design system that editors navigate confidently. The technical overhead is minimal, a handful of register_block_pattern_category() calls and consistent slug usage across pattern files.
The harder work is the naming and organization decisions: choosing categories that reflect how editors think rather than how code is organized, removing default categories that create duplicates, and resisting the temptation to create a category for every possible pattern type. Done well, the inserter becomes a tool editors reach for naturally rather than avoid.
If you are building on the foundations covered here, the next step is synced patterns, reusable blocks that propagate changes globally across every instance. That topic is covered in the next article in this series: How to Use Synced Patterns in Block Themes to Manage Global Content. For a deeper understanding of the full theme architecture that makes all of this possible, the complete block theme development guide is a solid reference.
