Using a Design System with the WordPress Block Editor: Block Types & Styles

How to streamline content creation and manage brand consistency by removing unneeded options

Code and block styles overlayed on a person typing on a laptop

This is Part 2 of a 2-part tutorial. For Part 1: theme.json, click here.

In Part 1 of our two-part blog series, we covered how to configure design systems in theme.json. Building on this, we can now utilize additional controls via code to remove unwanted default blocks and styles. 

For example, developers of a WordPress site using a design system may want to remove the audio block or the tag cloud block from the editor if they are not going to be used to ensure consistency while avoiding unnecessary design work. Other unused built-in block styling can also be adjusted or eliminated to build a cohesive set of design options in the editor. Limiting blocks and styles can also reduce overhead for creating new posts in the block editor by providing a smaller set of design options.

In this post, we’ll cover strategies that can be used by plugin and theme code to integrate a design system with the block editor.

Removing block types

The WordPress block editor includes a huge number of built-in blocks. It can be helpful to remove some default blocks in order to reduce design work and simplify content creation. This can be accomplished in the client with JavaScript or by using server-side PHP.

  1. To start, identify the block or blocks to remove from the editor. In this example, the “Latest Comments” block will be unregistered:

2. Next, find the corresponding block name in the Gutenberg core blocks reference guide. For the “Latest Comments” block, this is core/latest-comments:

3. Using the core/latest-comments name, we can remove it from the editor.

In JavaScript, use wp.blocks.unregisterBlockType:

wp.domReady( function() {
  wp.blocks.unregisterBlockType( 'core/latest-comments' );
} );

JavaScript for the block editor should be enqueued using the enqueue_block_editor_assets hook in PHP:

function wpvip_enqueue_block_js() {
  wp_enqueue_script(
    'wpvip-block-js',
    plugin_dir_url( __FILE__ ) . 'js/block.js',
    array( 'wp-blocks', 'wp-dom-ready', 'wp-edit-post' ),
    '0.0.1',
  );
}

add_action( 'enqueue_block_editor_assets', 'wpvip_enqueue_block_js' );

A more complex setup can be used to automatically build and manage block dependencies with the @wordpress/scripts package.

Note: While this post focuses primarily on interacting with blocks via the JavaScript API, best practices for using server-side PHP vs. client JavaScript for blocks change depending on your usage:

  • When modifying a built-in block, use JavaScript APIs. 
  • When modifying a third-party block, use JavaScript APIs.
  • When creating a custom block, use register_block_type with block.json in PHP. This will allow both server-side and client code to interact with your block.

We recommend using JavaScript for interacting with blocks, because this allows modification of both client-side and server-side registered blocks. Additionally, some block APIs are available only in JavaScript.

Unregistering core blocks is also possible using in PHP with the allowed_block_types_all filter:

add_filter( 'allowed_block_types_all', 'wpvip_unregister_blocks' );

function wpvip_unregister_blocks( $allowed_block_types ) {
  return array_filter( $allowed_block_types, function( $block_type ) {
    // Remove 'core/latest-comments' from allowed blocks
    return $block_type !== 'core/latest-comments';
  } );
}

Note that the allowed_block_types_all filter in PHP can also be used to provide an explicit allow list of blocks, excluding all others from being used in the editor:

add_filter( 'allowed_block_types_all', 'wpvip_unregister_blocks' );

function wpvip_unregister_blocks( $allowed_block_types ) {
  return [
    'core/paragraph',
    'core/heading',
    'core/group',
    /* ... other blocks to allow */
  ];
}

Note: Be careful with this approach, as this list will need to be maintained and updated with desired core or custom blocks. As mentioned above, this approach can be used only to limit blocks that are registered server-side (e.g., using block.json). Custom blocks that are client-side only need to be managed in JavaScript using wp.blocks.unregisterBlockType.

Replacing built-in block styles

Several core blocks in WordPress include preset block styles located in the contextual toolbar and inspector controls on the right side of the editor:

Above, the Button block includes a “Fill” and “Outline” style. These defaults, however, may not be desirable in a custom design system. They can be removed and replaced.

In JavaScript, use wp.blocks.unregisterBlockStyle with wp.blocks.registerBlockStyle to replace the default styles:

wp.domReady( function() {
  wp.blocks.unregisterBlockStyle( 'core/button', 'fill' );
  wp.blocks.unregisterBlockStyle( 'core/button', 'outline' );

  wp.blocks.registerBlockStyle( 'core/button', {
    name: 'primary',
    label: 'Primary',
    isDefault: true,
  } );

  wp.blocks.registerBlockStyle( 'core/button', {
    name: 'secondary',
    label: 'Secondary',
  } );
} );

The above code will remove the built-in “Fill” and “Outline” button styles, and add a new “Primary” style (default) and “Secondary” style:

New buttons will automatically be assigned the “Primary” style. The “Primary” style applies the `.is-style-primary` class to the button container, and “Secondary” applies `.is-style-secondary.` These styles can then be implemented in CSS. This article from WordPress contains more information about creating block styles.

There’s a PHP function available for unregistering block styles in unregister_block_style, but we don’t recommend it. Many block styles, including core blocks, are registered in client-side JavaScript, so it’s not possible to remove these styles using PHP. As mentioned above in “Removing block types,” we prefer client-side JavaScript to manage existing blocks for consistency.

Removing block variations

Variations are block settings presets that can be bundled to quickly configure a block. These are rare, but some core blocks include unwanted variations. For example, the built-in columns block includes several layout choices:

It may be desirable to remove variation presets. For this example, we’re going to remove the “25 / 50 / 25” variation. In JavaScript, variations can be removed via wp.blocks.unregisterBlockVariation:

wp.domReady( function() {
  wp.blocks.unregisterBlockVariation(
    'core/columns',
    'three-columns-wider-center'
  );
} );

“Three-columns-wider-center” is the variation name that corresponds with the “25 / 50 / 25” layout. This can be found by looking for the core block’s variations.js file and “name” property that corresponds with the unwanted variation. This will result in limiting the available block variations:

The block variations API is available only in JavaScript at this time.

In conclusion

Between theme.json customization and the APIs provided in this post, it’s possible to combine the WordPress block editor’s wide ecosystem with a design system and scope it down to a manageable size. 

Check out our related posts on how we manage design systems at WordPress VIP:

Authors

Alec Geatches, Senior Software Developer at Automattic

Enterprise WordPress developer and design systems enthusiast living in Taipei, Taiwan.

Gopal Krishnan, Senior Software Developer at Automattic

Gopal works on WordPress VIP’s decoupled WordPress offering, with an interest in design systems and Gutenberg. He’s based out of Sydney, Australia and has recently moved from Canada.

Get the latest content updates

Want to be notified about new content?

Leave your email address and we’ll make sure you stay updated.