Adding Icons to Custom Blocks

When you are building a new block, either for your own projects or to submit to the Plugin Repository, having your own custom icon is a great way to add distinction. It makes it easier to identify the block in the List View, and easier to see in the Block Inserter.

In this guide we’ll walk through adding Dashicons and custom SVG’s to your Custom ACF block, as well as custom native gutenberg blocks.

Using Dashicons

The easiest way to add your own icon is to use one of the icons from the Dashicons package. These icons are loaded by default with WordPress, so you just have to find one and add the name.

When you visit the Dashicons page it will randomly load one of the icons and give you a little information about the icon, with links to copy the CSS, HTML, or Glyph. All of the icons in the project have a name with ‘dashicons’ prefix. When you add the icon name you don’t need to include that prefix.

Using Custom SVG

You can also bring in your own svg graphic with both ACF as well as your custom coded block. I like to find my svg’s from The Noun Project, but you can use any svg or make your own.

Adding Custom Icons to Advanced Custom Fields Block

When you register your Custom ACF Block one of the settings is the ‘icon’ which you can specify the Dashicon name.

acf_register_block_type( array(
    'name'  => 'custom-block',
    'title' => __( 'Custom Block' ),
    'icon'  => 'trash'
    ...
) );

Here we are registering a new block and using the Dashicon ‘Trash’, which has a name of ‘dashicons-trash’. We only need the name itself, so we add ‘trash’ as a string for the ‘icon’ property.

You can also customize this icon with some additional settings. Instead of using just a string for the icon value, you can pass in an array with color settings alongside the name of the icon.

acf_register_block_type( array(
    'name'  => 'custom-block',
    'title' => __( 'Custom Block' ),
    'icon'  => array(
        'background' => '#21759b',
        'foreground' => '#ffffff',
        'src'        => 'trash'
    ),
    ...
) );

There are three attributes of the array. The background, foreground, and src. Here we set the background to WordPress Blue, the foreground to white, and now the src is where we add the name of the icon. It will now look like this:

If you don’t find an icon that best represents your new block, you can also use your own svg graphic. Just add the string of your svg as the value for the ‘icon’.

acf_register_block_type( array(
    'name'  => 'custom-block',
    'title' => __( 'Custom Block' ),
    'icon'  => '<svg viewBox="1 -1 100 100"xmlns="http://www.w3.org/2000/svg"><path d="M65.1 17.8V6.5H35.8v11.3H11.4v6.1h7.3l5.2 67.7h53.3l5.2-67.7h8.3v-6.1H65.1zm-6-5.3v5.2H41.9v-5.2h17.2zM29.4 85.4l-4.7-61.6h51.5l-4.8 61.6h-42z"/><path d="M47.4 32.6h6.1v44.3h-6.1zm17.301 44.486-6.09-.331 2.407-44.334 6.09.331zm-28.515-.001-2.401-44.333 6.09-.33 2.402 44.333z"/></svg>'
    ...
) );

With this you level of control you can add anything you want for the icon of your block. Here’s the custom icon added above:

Optimizing your SVG

Depending on where you got or exported your SVG, there might be a lot of unnecessary elements in the file. There are a few resources that I like to use when getting an SVG ready.

  • SVGOMG – Minimize and clean up the SVG
  • SVG CROP – If your SVG has extra white space around the icon

With these tools you can clean up your SVG file and then copy and past the code into your block registration.


Adding Custom Icons to your own Custom Coded Block.

When building your own custom block it is encouraged that you use the block.json metadata file to register your block on the server. There are lots of reasons to use the block.json file, read more about the file in the developer handbook.

One of the properties in the block.json file is icon and is used for registering an icon using one of the Dashicons. It’s important to note that you cannot use a custom svg in the block.json, and instead have to use the client side registration. But we’ll get to more on that later.

Just like when adding the Dashicon name we strip away the ‘dashicons’ prefix and just use the name of the icon.

{
    ...
    "icon": "trash"
    ...
}

Regardless if you plan to add a custom svg icon, you should still pick a Dashicon to add to your theme.json.

Custom SVG Icons in Custom Coded Block

When you register your block on the client side with JavaScript, you can provide an ‘icon’ property that will override the property that was set in the block.json file.

To register your custom block you use the registerBlockType function that is in the @wordpress/blocks package. That function takes two properties, first the name of your block, and second the attributes. The attributes object has an optional icon property that will override the block.json property.

If you like your Dashicons choice, you can also add a custom background and foreground colors similar to the ACF Blocks registration. Just add an object with the background, foreground, and src properties.

import { registerBlockType } from '@wordpress/blocks';

import json from './block.json';
import Edit from './edit';
import save from './save';

const { name } = json;

registerBlockType(name, {
    icon: {
        background: '#21759b',
        foreground: '#ffffff',
        src: 'trash',
    },
    edit: Edit,
    save,
});

When you want to use your own svg there are a couple way to add it in. You can replace the src in your icon object with the svg. With this object can either use the color properties as well, or just omit them.

Here I’ve added the SVG component,

import { registerBlockType } from '@wordpress/blocks';
import { SVG, Path } from '@wordpress/components';

import json from './block.json';
import Edit from './edit';
import save from './save';

const { name } = json;

registerBlockType(name, {
    icon: {
        src: (
            <SVG xmlns="http://www.w3.org/2000/svg" viewBox="1 -1 100 100">
                <Path d="M65.1 17.8V6.5H35.8v11.3H11.4v6.1h7.3l5.2 67.7h53.3l5.2-67.7h8.3v-6.1H65.1zm-6-5.3v5.2H41.9v-5.2h17.2zM29.4 85.4l-4.7-61.6h51.5l-4.8 61.6h-42z" />
                <Path d="M47.4 32.6h6.1v44.3h-6.1zm17.301 44.486-6.09-.331 2.407-44.334 6.09.331zm-28.515-.001-2.401-44.333 6.09-.33 2.402 44.333z" />
            </SVG>
        ),
    },
    edit: Edit,
    save,
});

This will work and now you have your own svg icon as the icon for your custom block.

If you’re like me, you prefer to keep your registerBlockType function a little cleaner and import anything you might use in that function.

So now I’ll move my svg icon to it’s own file.

import { SVG, Path } from '@wordpress/components';

export const trash = (
    <SVG xmlns="http://www.w3.org/2000/svg" viewBox="1 -1 100 100">
        <Path d="M65.1 17.8V6.5H35.8v11.3H11.4v6.1h7.3l5.2 67.7h53.3l5.2-67.7h8.3v-6.1H65.1zm-6-5.3v5.2H41.9v-5.2h17.2zM29.4 85.4l-4.7-61.6h51.5l-4.8 61.6h-42z" />
        <Path d="M47.4 32.6h6.1v44.3h-6.1zm17.301 44.486-6.09-.331 2.407-44.334 6.09.331zm-28.515-.001-2.401-44.333 6.09-.33 2.402 44.333z" />
    </SVG>
);
import { registerBlockType } from '@wordpress/blocks';

import json from './block.json';
import Edit from './edit';
import save from './save';
import { trash } from './icons';

const { name } = json;

registerBlockType(name, {
    icon: trash,
    edit: Edit,
    save,
});

The advantage to this approach is you now have a file set up for any other icons that you might use throughout your block. Just add those as additional exports to the icons.js file and import where you need them.

If you have a plugin with multiple blocks, you could have a single icon file in a shared directory and export all of the icons from that one file. Then you don’t need to create a separate file for each of your blocks.

One Comment

Brad December 13, 2023 Reply

Excellent! the only way that I could get it to work, so, HUGE THANK YOU! Any tips on doing the same for a custom block categories icon?

Leave a Reply