--- title: Add an icon to the WordPress button block description: The core Button block has no icon picker. A small plugin extends the sidebar so editors can choose an icon and position without a code deploy. source: https://steem.dev/blog/wordpress-button-block-icon-picker published: 2026-11-05 updated: 2026-11-05 site: Steem — AI WordPress plugin generator --- # Add an icon to the WordPress button block The core Button block does one thing cleanly: it creates a linked button. What it does not ship is an icon. Getting an icon onto a button in the block editor means registering a block style, writing the SVG into PHP, and deploying the change. That works for a fixed design under developer control. It falls apart when a client wants to swap an icon, add a new one, or try it in a different position, because each change is a code push. A plugin that extends the Button block with an icon picker panel moves that decision into the editor. The developer stops being the person who deploys every arrow change. The client opens the sidebar, picks an icon, sets whether it sits before or after the label, and publishes. ## What one build covers - Icon picker panel added to the Button block inspector sidebar - Position setting: icon before or after the button label - Around 20 bundled SVG icons for common use cases - Frontend icon injection via the PHP render filter for core/button blocks ## What it does not cover - Icon display in the editor canvas: icons appear on the frontend only - Custom SVG upload through the media library - Icons on Button blocks from themes, page builders or other plugins - Hover effects, icon color overrides or animation per icon ## The prompt ```text Build a WordPress plugin called WP Button Icons. It extends the core Button block by adding an icon picker panel to the block inspector sidebar. When a Button block is selected in the editor, a new panel appears with two settings: a grid of icon thumbnails to choose from, and a position toggle for before or after the button label. The plugin bundles around 20 common SVG icons covering directional arrows, download, external link, check, close, phone, envelope, search, plus, cart and star. The selected icon name and position are stored as block attributes alongside the button's existing settings. On the frontend, a PHP filter reads those attributes for every core/button block and injects the chosen SVG inside the anchor element at the chosen position. The editor canvas shows the button label only; the icon appears on the frontend. No separate block and no shortcode: the plugin extends the existing core/button block. ``` ## Why block styles leave icon management to the developer Block styles registered with register_block_style() add a named variant to the block's Style panel. The standard approach for button icons is to register one style per icon, embedding the SVG as a CSS background-image or pseudo-element in the stylesheet. That works, but it ties every icon to a stylesheet entry, which means every new icon triggers a child-theme edit and a deployment. The editor provides no way to pick a style and also choose where the icon sits, so positions end up as separate styles too: 'Arrow left', 'Arrow right', 'Download with arrow'. The Style panel fills with variants, and the client still cannot make a change without asking a developer. The underlying issue is that block styles control appearance through CSS classes, not block attributes. An attribute approach stores the icon choice in the block's own data, so the same PHP render step that handles 'bold text, blue background' can also handle 'arrow icon, after label'. ## What the sidebar panel stores and where the icon comes from When a Button block is selected, a new panel in the block inspector shows a grid of icon thumbnails and a before/after position toggle. Picking an icon writes the choice into the block's attributes. Those attributes travel with the block in post_content as part of the block comment delimiter, alongside the button's existing link and color settings. Nothing is stored in a separate database table. On the frontend, a PHP render filter runs for every Button block before its HTML reaches the browser. It reads the icon name from the parsed block attributes, finds the matching SVG in the plugin's bundled set, and injects it inside the anchor element at the chosen position. The editor canvas shows the button text only; the icon appears on the frontend. The plugin ships with around twenty common SVGs: directional arrows, download, external link, check, close, phone, envelope, search, plus, cart and star. For a typical site, that set covers most button designs a client will reach for. ## When the bundled set runs short If a client needs an icon outside the bundled set, the practical path is a follow-up message describing the shape. The plugin adds it to the icon array, names it, and the picker shows it on the next load. The same message can add a custom SVG field to the panel, letting anyone paste raw SVG markup as a one-off icon without touching the plugin's PHP. The plugin targets core/button blocks specifically. A Button block from a theme, a page builder or any other plugin has a different block name and is not processed. If those blocks also need icons, the render filter and attribute registration need to target their block names instead. One behaviour to set expectations around: the editor canvas does not show the icon. It appears only on the published or previewed page, where the PHP render filter runs. That is a consequence of modifying block output server-side rather than through the block's own JavaScript render path, and it is the trade-off for not needing to override or fork the core Button block's editor component. ## Questions ### What happens to buttons if the plugin is deactivated? The icon attribute stays in the block data inside post_content, but without the render filter running the SVG is not injected into the HTML. The button continues to work and links correctly. No data is lost. Reactivating the plugin restores the icon on the frontend. --- Source: https://steem.dev/blog/wordpress-button-block-icon-picker Build this plugin: https://steem.dev/app