Adding Icons for your Gutenberg Categories

Posted by Ronald Huereca / April 24, 2020 /

Notice: Undefined property: WP_Block_Type::$supports in /www/wp-content/plugins/gutenberg/lib/blocks.php on line 241 Notice: Undefined property: WP_Block_Type::$supports in /www/wp-content/plugins/gutenberg/lib/blocks.php on line 241 Notice: Undefined property: WP_Block_Type::$supports in /www/wp-content/plugins/gutenberg/lib/blocks.php on line 241 Notice: Undefined property: WP_Block_Type::$supports in /www/wp-content/plugins/gutenberg/lib/blocks.php on line 241 Notice: Undefined property: WP_Block_Type::$supports in /www/wp-content/plugins/gutenberg/lib/blocks.php on line 241

For block collections, it’s useful to group your blocks into a category for organizational purposes. In this tutorial, I will. show you how to create a category for your blocks and how to add a custom SVG icon.

Gutenberg Icons
Gutenberg Category Icons

Adding the Category

Adding the category is pretty simple. It all starts with the block_categories filter. Let’s dive into the code needed. For example, here’s how Paid Memberships Pro does it for their block category:

/**
 * Add PMPro block category
 */
function pmpro_place_blocks_in_panel( $categories, $post ) {
	return array_merge(
		$categories,
		array(
			array(
				'slug'  => 'pmpro',
				'title' => __( 'Paid Memberships Pro', 'paid-memberships-pro' ),
			),
		)
	);
}
add_filter( 'block_categories', 'pmpro_place_blocks_in_panel', 10, 2 );

There’s a third argument called icon that you can use to assign a dashicon to the block category. For example, re-using the above code, you could do:

function pmpro_place_blocks_in_panel( $categories, $post ) {
	return array_merge(
		$categories,
		array(
			array(
				'slug'  => 'pmpro',
				'title' => __( 'Paid Memberships Pro', 'paid-memberships-pro' ),
				'icon'  => 'editor-table',
			),
		)
	);
}
add_filter( 'block_categories', 'pmpro_place_blocks_in_panel', 10, 2 );

A more elegant example is on a post entitled Creating a Block Category if you wish to check that one out. Here’s the result of adding the above Dashicon to the block category.

Gutenberg Category With Icon
Gutenberg Category With Icon

It’s really that simple. But what if you want to add a custom icon that isn’t a dashicon?

Adding a Custom Icon

To add a custom icon, you need an SVG version of your icon. It should be lightweight so it doesn’t balloon your file size, and there are some caveats to look out for. In the example below, I’ll be using JSX to include the icon. You’d include it either as a component, or inline in your block initialization script, which is the approach I’ll be taking.

For example, here’s some raw SVG code that is JSX-friendly (I grabbed it from Google’s Material Library).

<svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M11.99 2c-5.52 0-10 4.48-10 10s4.48 10 10 10 10-4.48 10-10-4.48-10-10-10zm3.61 6.34c1.07 0 1.93.86 1.93 1.93 0 1.07-.86 1.93-1.93 1.93-1.07 0-1.93-.86-1.93-1.93-.01-1.07.86-1.93 1.93-1.93zm-6-1.58c1.3 0 2.36 1.06 2.36 2.36 0 1.3-1.06 2.36-2.36 2.36s-2.36-1.06-2.36-2.36c0-1.31 1.05-2.36 2.36-2.36zm0 9.13v3.75c-2.4-.75-4.3-2.6-5.14-4.96 1.05-1.12 3.67-1.69 5.14-1.69.53 0 1.2.08 1.9.22-1.64.87-1.9 2.02-1.9 2.68zM11.99 20c-.27 0-.53-.01-.79-.04v-4.07c0-1.42 2.94-2.13 4.4-2.13 1.07 0 2.92.39 3.84 1.15-1.17 2.97-4.06 5.09-7.45 5.09z"/><path d="M0 0h24v24H0z" fill="none"/></svg>

An example of a non-JSX friendly SVG is shown below:

<svg id="Layer_1" data-name="Layer 1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" viewBox="0 0 400 400"><defs><clipPath id="clip-path" transform="translate(-106 -196)"><path d="M476.41,296.5a1.17,1.17,0,0,0,0-.26c0-.19-.05-.37-.08-.57a1.14,1.14,0,0,1-.06-.25c-.06-.25-.1-.48-.17-.72a1.89,1.89,0,0,0-.11-.25,2,2,0,0,0-.17-.47,2.36,2.36,0,0,0-.12-.28c-.07-.16-.16-.32-.23-.47s-.07-.14-.11-.22-.26-.43-.38-.62a2.43,2.43,0,0,0-.14-.2,3.64,3.64,0,0,0-.35-.45,2.09,2.09,0,0,1-.14-.17c-.14-.19-.32-.34-.46-.53,0,0,0,0-.07-.05-.17-.17-.37-.36-.56-.52l-.17-.13c-.14-.12-.3-.23-.44-.34l-.23-.14a3.74,3.74,0,0,0-.49-.3c-.05,0-.14-.07-.18-.11l-.59-.29-.14-.05s0,0,0,0L309.66,217.45a9.07,9.07,0,0,0-7.29,0L141.08,289.09s0,0,0,0l-.13.05-.58.29c-.06,0-.14.07-.19.11s-.34.2-.5.3l-.22.14c-.15.11-.3.24-.46.34a.91.91,0,0,1-.16.13c-.2.16-.39.35-.58.52l-.05.05a5.82,5.82,0,0,0-.46.53.76.76,0,0,0-.15.17c-.13.15-.23.31-.34.45l-.15.2a3.9,3.9,0,0,0-.37.62l-.11.22c-.07.17-.16.33-.23.48s-.09.2-.13.29-.13.33-.18.48a1.31,1.31,0,0,1-.09.26c-.07.23-.12.48-.17.72a1.83,1.83,0,0,0-.06.25,5.62,5.62,0,0,0-.09.57c0,.09,0,.16,0,.25,0,.27,0,.54,0,.81V494.55a9,9,0,0,0,5.32,8.2l161.46,71.71.06,0a4.41,4.41,0,0,0,.72.26.91.91,0,0,0,.14.07c.27.07.56.14.84.23,0,0,0,0,0,0a9.1,9.1,0,0,0,3.7,0s0,0,0,0c.29,0,.58-.16.84-.23,0,0,.09,0,.15-.07.25-.07.48-.17.72-.26l.05,0L471.1,502.75a9,9,0,0,0,5.33-8.2V297.34c0-.27,0-.54,0-.81l0,0ZM306,235.39,445.4,297.3,306,359.21,166.64,297.3,306,235.39Zm-152.49,75.7,143.52,63.76V552.44L153.53,488.69V311.09ZM315,552.44V374.85l143.52-63.76v177.6L315,552.44Z" fill="none"/></clipPath></defs><image width="400" height="400" xlink:href="data:image/png;base64 (code intentionally shortened)

Some things to look out for when converting your SVG for use in JSX:

  1. Look for any style attributes. In JSX, style must be an object and not a string. If you don’t need the style attribute, simply remove it. If you do need it, it’ll have to be in style={{backgroundColor: red}} format.
  2. Look for HTML/XML-specific attributes such as xmlns:clink. It’s better to remove those attributes.
  3. Convert xlink:href to JSX-friendly attributes such as xlinkHref.

I’m sure there are others. Please leave a comment below if you’re aware of other caveats.

Now that we have our SVG, how do we add it in? The code is fairly simple (I’m picking on Paid Memberships Pro again):

( function() {
	const PMProSVG = <svg xmlns="http://www.w3.org/2000/svg" height="24" viewBox="0 0 24 24" width="24"><path d="M11.99 2c-5.52 0-10 4.48-10 10s4.48 10 10 10 10-4.48 10-10-4.48-10-10-10zm3.61 6.34c1.07 0 1.93.86 1.93 1.93 0 1.07-.86 1.93-1.93 1.93-1.07 0-1.93-.86-1.93-1.93-.01-1.07.86-1.93 1.93-1.93zm-6-1.58c1.3 0 2.36 1.06 2.36 2.36 0 1.3-1.06 2.36-2.36 2.36s-2.36-1.06-2.36-2.36c0-1.31 1.05-2.36 2.36-2.36zm0 9.13v3.75c-2.4-.75-4.3-2.6-5.14-4.96 1.05-1.12 3.67-1.69 5.14-1.69.53 0 1.2.08 1.9.22-1.64.87-1.9 2.02-1.9 2.68zM11.99 20c-.27 0-.53-.01-.79-.04v-4.07c0-1.42 2.94-2.13 4.4-2.13 1.07 0 2.92.39 3.84 1.15-1.17 2.97-4.06 5.09-7.45 5.09z"/><path d="M0 0h24v24H0z" fill="none"/></svg>;
	wp.blocks.updateCategory( 'pmpro', { icon: PMProSVG } );
} )();

I placed the above code in my initialization JavaScript file for the block.

Now here’s what the icon looks like now.

Gutenberg Category SVG Icon
Gutenberg Category SVG Icon

That’s it!

Debate Over Category Icons

There’s some debate over if block categories should have icons. I’m of the position of, why not?

Others have mentioned that the icons should blend in with the existing Gutenberg scheme (black and white). Other block category icons are full on color mode such as JetPack and WooCommerce.

I’m unsure of what the best practices are, but in my opinion it’s your plugin, so do with it as you wish. Users will be the ones complaining, while others may look at the icon, sigh in frustration, and move on with their lives.

If you have your own perspective, please leave a comment below.

Conclusion

Within this article I showed you how to create a custom block category, add a block icon, and went over briefly a point of contention in regards to block categories having icons.

Notice: Undefined property: WP_Block_Type::$supports in /www/wp-content/plugins/gutenberg/lib/blocks.php on line 241
Developer at MediaRon
Ronald Huereca is the CEO of MediaRon LLC and enjoys WordPress plugin and theme development.

Connect with the Author

Posted in

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top