By default, the WordPress block editor makes every registered block available from the inserter, core blocks, plugin blocks, theme blocks, and anything else that’s been registered on the site. For a developer working on their own site this is fine, but for client sites it’s overwhelming. A client editing a blog post doesn’t need access to the Query Loop block, the Navigation block, the Site Title block, or any of the dozens of template-level blocks WordPress registers. Showing them everything creates confusion and support requests.
The allowed_block_types_all filter lets you define exactly which blocks are available, on a per-post-type basis if needed. The result is a clean, focused inserter with only the tools that make sense for the content being edited.
The Code
Add this to your functions.php or a site-specific plugin. The filter receives the current allowed blocks value and an editor context object. Returning an array of block type slugs restricts the inserter to only those blocks. Returning true allows all blocks.
Reading the Editor Context
The $editor_context object contains information about what’s being edited. The snippet checks $editor_context->post first, this is a WP_Post object when editing a post, but may be empty in other editor contexts like site editing or widget areas. Returning the original $allowed_blocks value unchanged when the post object is absent ensures those contexts aren’t accidentally restricted.
Choosing Which Blocks to Include
The block lists in the snippet are starting points, adjust them to match your actual content needs. A few considerations when building your list:
Block slugs follow the format namespace/block-name. Core WordPress blocks use the core/ namespace. Plugin blocks use the plugin’s own namespace, for example Kadence blocks use kadence/ and WooCommerce uses woocommerce/.
Some blocks have child blocks that must be included separately. core/list requires core/list-item. core/buttons requires core/button. core/columns requires core/column. If you include a container block without its child, the block will appear broken in the editor.
The core/html block gives editors a raw HTML input field, which is a safety consideration on sites with non-technical clients. Include it only if you trust the editors on that post type.
Performance Consideration
Restricting allowed blocks doesn’t prevent those blocks from being registered or their assets from loading, it only hides them from the inserter. For a true performance improvement, blocks that are never used can be dequeued using wp_dequeue_script() and wp_dequeue_style(), but that’s a more involved process. The allowed_block_types approach is the practical solution for most sites.
add_filter( 'allowed_block_types_all', function( $allowed_blocks, $editor_context ) {
// Only apply restrictions to specific post types
if ( empty( $editor_context->post ) ) {
return $allowed_blocks;
}
$post_type = $editor_context->post->post_type;
// Simplified block set for blog posts
if ( $post_type === 'post' ) {
return [
'core/paragraph',
'core/heading',
'core/image',
'core/list',
'core/list-item',
'core/quote',
'core/code',
'core/preformatted',
'core/separator',
'core/html',
'core/embed',
'core/buttons',
'core/button',
'core/table',
'core/pullquote',
];
}
// Even simpler set for pages
if ( $post_type === 'page' ) {
return [
'core/paragraph',
'core/heading',
'core/image',
'core/list',
'core/list-item',
'core/buttons',
'core/button',
'core/separator',
'core/html',
'core/columns',
'core/column',
'core/group',
];
}
// Return true to allow all blocks for other post types
return true;
}, 10, 2 );
