Skip to content

Heroicons for WordPress


My friend Joey was working on a way to incoportate an icon picker into a custom WordPress block using Advanced Custom Fields. We both love using Heroicons, so naturally that would be the source of the icon set that we would use.

We agreed on splitting the work a bit - he would work on the ACF part, using Alpine.js to open a modal, where you would then search for the icon you wanted. I would do the actual search part mimicing the search experience found on the Heroicons website.

Once I had the search mechanism working, I thought that perhaps this could be a great standalone WordPress block, without any dependencies on ACF or some other theme. So, I set out to create a plugin, which would inject this new block into the list of available blocks when activated.

Creating a custom WordPress block

I don’t have the impression that the official documentation around WordPres block development is known for being very good. Indeed, I struggled a bit to find a starting point that made sense for wanted to do; thankfully, I came across this post on CSS Tricks which had just what I was looking for, and I was off. In short, it details what a block is, and how you can get started leveraging WordPress’ own Node libraries.

For example, this one command scaffolds all of the files you might need to get started building a block inside of a plugin:

npx @wordpress/create-block

Follow the prompts to fill in the details about the block you’re buildings, and you’re set.

Since I already had the logic mapped out in the ACF/Alpine version with Joey, I needed to translate that into the “native” way; that is, using React (abstracted as @wordpress/components) to build the UI using what WordPress has to offer from its list of UI elements for the block editor.

Leveraging blocks.json

One of the ways that has emerged in defining custom blocks is the use of blocks.json to specify what kind of stuff the block can do. It’s as easy as adding a few items to the “supports” object, to list out some of the basic controls that come out the the box, like alignment, color, and spacing.

"supports": {
    "align": true,
    "color": true,
    "backgroundColor": true,
    "spacing": {
        "padding": true
    }
},

Like magic, the edit function in the block spits out the result of these controls automatically, in the blockProps object. I don’t even need to hook up any React state for these ones.

<div   { ...blockProps }>
 // block stuff inside here
</div>

The rest I was able to wire together with a RangeControl to set the size of the icon, for example.

Otherwise, the “attributes” object in block.json is the data that will be passed to the thing that renders your block in the front-end.

"attributes": {
    "selectedIcon": {
        "type": "object"
    },
},

In my case, I wanted to use a PHP file to create a dynamic block (which isn’t strictly necessary in this case), so I have a render.php file which can access the attributes easily. In my case, I pass in an object called selectedIcon(which has other data included), and the icon itself is accessed like selectedIcon.svg in the JavaScript object. This gets passed into the render template, and gets added as key on an associative array called $attributes in the template:

<div <?php echo get_block_wrapper_attributes(); ?>>
    <?php echo $attributes['selectedIcon']['svg']; ?>
</div>

Finally, the basic logic for the icon block was complete, and you can the result on Github. Holler at me on twitter if you think I should look at getting this into the official WordPress plugin directory for all to use.

heroicon block selecting icon