Custom SVG Icons for Gutenberg Blocks in WordPress
This post covers a straightforward way to use custom SVG icons in Gutenberg blocks.
You can use an SVG icon for your block, to appear
The content of this post is intended as an updated alternative to some of the methods covered in older tutorials such as Zac Gordon’s 2017 post How to Add Custom Icons to Gutenberg Editor Blocks in WordPress.
Install Dependencies
Use npm
or yarn
to install the @svgr/webpack
and url-loader
dependencies:
yarn add @svgr-webpack --dev
yarn add url-loader --dev
Add the following to the rules
array in your webpack config:
{
test: /\.svg$/,
use: [ '@svgr/webpack', 'url-loader' ],
},
If you are using the boilerplate @wordpress/scripts
included webpack.config
, a convenient example is in the docs where the boilerplate config is loaded and spread (via the spread operator) into a custom config file where you can then make customizations of your own, such as adding the above block to support SVG’s.
The docs actually use @svgr/webpack
as their example of a the customized webpack.config
that extends the boilerplate, but the docs don’t cover how to actually make use of the @svgr/webpack
package.
For convenience, I copied the following example from the WordPress Developer Docs:
const defaultConfig = require("@wordpress/scripts/config/webpack.config")
module.exports = {
...defaultConfig,
module: {
...defaultConfig.module,
rules: [
...defaultConfig.module.rules,
{
test: /\.svg$/,
use: ["@svgr/webpack", "url-loader"]
}
]
}
}
Using SVG Icons as Components
You can now import icons as Reqct Components in your blocks.js
(or whichever) file where you call registerBlockType()
to register a new block:
import { ReactComponent as MyIcon } from '../../assets/svg/ui/icon.svg'
As an aside, note that you also have the option of importing a base-64-encoded svg via the default export created by @svgr/webpack
: import myIconSvg from '../../assets/svg/ui/icon.svg'
Specifying the SVG Icon for your Block
In the block configuration object passed to registerBlockType()
, specify your icon component without encapsulating it in a JSX tag:
registerBlockType( 'example/my-block', {
...
icon: MyIcon
...
}
Using SVG Icon Components in Block edit() and save() Methods
You can also use the component you imported (e.g. <MyIcon />
) as a JSX tag in your edit
and save
functions.
registerBlockType( 'example/my-block', {
...
icon: MyIcon
...
edit: () => (<div><MyIcon /></div>)
...
}
Note About SVG’s
Not all SVG’s are created equal. I have had success with those that define a square viewBox
and set a width
and height
of “1em”.