By default when you run npx @wordpress/create-block you’ll get a preformed block with a smiley face icon like this:
In the method of Guteberg block registration that the NPM @wordpress/create-block uses the arguments are stored in JSON at in block.json.
One option worth mentioning is that you can use any of the available dashicons for your custom Gutenberg block simply by changing the specified icon name. Underneath the hood the dashicons are loaded into React using their SVG’s rather than the regular dashicon icon font. And this is why we can use the same approach to swap in a custom SVG icon.
In this example shown below I’m overriding the definition of “icon” in block.json and specifying it in the index.js file as an argument for the registerBlockType(). While I’m still using a dashicon in this example, this is the first step towards supporting a custom SVG icon for our Gutenberg block. What we’ll do next is make an SVG element and pass it here in place of the dashicon named icon. The registerBlockType() function is checking for either option and will handle the rest.
For my project I headed over to FontAwesome where I have a premium account and picked out an icon that I think works well for a “team” of people, it’s actually designed to represent students in a classroom but I think it works well for this purpose also. I exported the SVG and imported it into Figma where I swapped the colors:
After exporting the SVG from Figma I drop the file into the block I’m working on and open it in my editor (Atom). We won’t actually use the SVG file, instead we’ll be taking the definition of the SVG path found the variable “d”.
The screenshot below shows the critical part of the solution. First we load “createElement” from WordPress React element and then we use it to create our SVG element. The SVG element is really 2 different elements, a path tag nested inside the svg tag. Hopefully you have good copy and paste skills (arguably the most important skill for any developer). You’ll to get the “d” path from your SVG file and make sure you don’t get any other part of the tag. For large SVG definitions pro tip is to zoom out a lot to make the selection of the long text easier.
Here is how it turned out after my initial render of the custom SVG in the Saber Teams Gutenberg block:
If you’re really observant you might be able to see that the positioning of the icon seems just slightly off. It’s 2.5px off to be exact. That’s because the Gutenberg editor wants the icon to be 20×20 but this icon I’ve used is 20×15. The box it sits in is still 20×20 and it renders from the top causing it to look like it’s about 2.5px higher than it should be. The only solution… is to entirely rebuilt Gutenberg.
Next I head back into Figma to adjust the icon and make it 20×20. One option is to put a background 20×20 behind the icon and then vertically center the icon into it.
As I tinkered around in Figma I added a solid line under the icon to give it a bit more height and because I thought it adds something to the icon as well. I then experimented with a black background, let’s see how much this would stand out in Gutenberg?
I realized after exporting and updating the code that the black background did not show up unless I use the fill parameter. It’s a really useful thing to make SVG elements (or any elements) this way because it opens up a lot of interesting possibilities. Here is what I ended up with after trying a few different design variations: