{"id":369199,"date":"2026-09-19T10:29:49","date_gmt":"2026-09-19T10:29:49","guid":{"rendered":"https:\/\/wordpress.org\/plugins\/icon-library\/"},"modified":"2026-09-19T14:51:28","modified_gmt":"2026-09-19T14:51:28","slug":"sf-icon-manager","status":"publish","type":"plugin","link":"https:\/\/arg.wordpress.org\/plugins\/sf-icon-manager\/","author":20174602,"comment_status":"closed","ping_status":"closed","template":"","meta":{"version":"0.3.4","stable_tag":"0.3.4","tested":"7.1.1","requires":"6.6","requires_php":"8.3","requires_plugins":null,"header_name":"SVG Forge Icon Manager","header_author":"svgforge","header_description":"Gutenberg block that inserts SVG icons from a sprite file (ico.svg) via <use> and links them.","assets_banners_color":"","last_updated":"2026-09-19 14:51:28","external_support_url":"","external_repository_url":"","donate_link":"","header_plugin_uri":"","header_author_uri":"","rating":0,"author_block_rating":0,"active_installs":0,"downloads":48,"num_ratings":0,"support_threads":0,"support_threads_resolved":0,"author_block_count":0,"sections":["description","installation","faq","changelog"],"tags":{"0.3.3":{"tag":"0.3.3","author":"wpdynamics","date":"2026-09-19 10:52:34","revision":3703214},"0.3.4":{"tag":"0.3.4","author":"wpdynamics","date":"2026-09-19 14:51:28","revision":3703382}},"upgrade_notice":[],"ratings":[],"assets_icons":{"icon-128x128.png":{"filename":"icon-128x128.png","revision":3703245,"resolution":"128x128","location":"assets","locale":"","width":128,"height":128},"icon-256x256.png":{"filename":"icon-256x256.png","revision":3703245,"resolution":"256x256","location":"assets","locale":"","width":256,"height":256}},"assets_banners":[],"assets_blueprints":{},"all_blocks":{"sf-icon-manager\/svg-icon":{"$schema":"https:\/\/schemas.wp.org\/trunk\/block.json","apiVersion":3,"name":"sf-icon-manager\/svg-icon","version":"0.2.0","title":"SVG Icon","category":"widgets","icon":"format-image","description":"Inserts an SVG icon from the plugin SVG Forge Icon Manager and can be linked.","keywords":["icon","svg","symbol","sprite"],"textdomain":"sf-icon-manager","supports":{"html":false,"align":["left","center","right"],"anchor":true,"className":true,"color":{"text":true,"background":true,"link":false,"heading":false,"button":false,"__experimentalSkipSerialization":true,"__experimentalDefaultControls":{"text":true,"background":true}},"spacing":{"margin":true,"padding":true,"__experimentalSkipSerialization":["padding"],"__experimentalDefaultControls":{"margin":true,"padding":false}},"dimensions":{"width":true,"__experimentalSkipSerialization":["width"],"__experimentalDefaultControls":{"width":true}}},"selectors":{"root":".wp-block-sf-icon-manager-svg-icon .svg-icon__svg","css":".wp-block-sf-icon-manager-svg-icon","spacing":{"margin":".wp-block-sf-icon-manager-svg-icon"}},"attributes":{"symbolId":{"type":"string","default":""},"url":{"type":"string","default":""},"opensInNewTab":{"type":"boolean","default":false},"rel":{"type":"string","default":""},"label":{"type":"string","default":""},"width":{"type":"string","default":"48px"},"height":{"type":"string"}},"editorScript":"file:.\/index.js","editorStyle":"file:.\/index.css","style":"file:.\/style-index.css","render":"file:.\/render.php"}},"tagged_versions":["0.3.3","0.3.4"],"block_files":[],"assets_screenshots":{"screenshot-1.jpg":{"filename":"screenshot-1.jpg","revision":3703382,"resolution":"1","location":"assets","locale":"","width":1200,"height":869}},"screenshots":{"1":"Symbol picker in the Gutenberg editor with a live preview of all icons from the sprite file."}},"plugin_section":[],"plugin_tags":[148076,498,21077,2904],"plugin_category":[50],"plugin_contributors":[281572],"plugin_business_model":[],"class_list":["post-369199","plugin","type-plugin","status-publish","hentry","plugin_tags-gutenberg","plugin_tags-icons","plugin_tags-sprite","plugin_tags-svg","plugin_category-media","plugin_contributors-wpdynamics","plugin_committers-wpdynamics"],"banners":[],"icons":{"svg":false,"icon":"https:\/\/ps.w.org\/sf-icon-manager\/assets\/icon-128x128.png?rev=3703245","icon_2x":"https:\/\/ps.w.org\/sf-icon-manager\/assets\/icon-256x256.png?rev=3703245","generated":false},"screenshots":[{"src":"https:\/\/ps.w.org\/sf-icon-manager\/assets\/screenshot-1.jpg?rev=3703382","caption":"Symbol picker in the Gutenberg editor with a live preview of all icons from the sprite file."}],"raw_content":"<!--section=description-->\n<p>The SVG Forge Icon Manager Block loads a central SVG sprite file (by default the bundled <code>sprite.svg<\/code>), shows all contained <code>&lt;symbol&gt;<\/code> elements in a convenient picker and inserts the selected icon as <code>&lt;svg&gt;&lt;use href=\"\/wp-content\/plugins\/sf-icon-manager\/sprite.svg#symbol-id\"&gt;<\/code> into your content.<\/p>\n\n<p>The SVG sprite is a static <a href=\"https:\/\/css-tricks.com\/svg-symbol-good-choice-icons\/\">SVG fragment<\/a> file loaded by the browser via <code>&lt;use&gt;<\/code> \u2014 no JS on the frontend. Since you own the sprite file, every icon stays small, cacheable and fully under your control \u2014 exactly the way a hand-built icon set should be maintained.<\/p>\n\n<h4>Who is this plugin for?<\/h4>\n\n<p>This plugin is primarily aimed at advanced theme and plugin developers. It does not give you a code-free icon manager: every icon must first exist as a <code>&lt;symbol&gt;<\/code> in a sprite file that you own, build and version.<\/p>\n\n<p>Since WordPress 7.1, core ships its own icon system (<code>wp_register_icon_collection()<\/code>, <code>wp_register_icon()<\/code>, <code>wp_get_icon()<\/code>): icons then automatically appear in the native Icon block's picker and in the REST API, and can be rendered directly in PHP. If you only need a few icons and can register them in code, use core instead \u2014 this plugin is then unnecessary.<\/p>\n\n<p>The fragment approach has advantages when you run a real sprite pipeline:<\/p>\n\n<ul>\n<li>Full SVG via <code>&lt;use&gt;<\/code>: stroke-based icons, gradients, <code>currentColor<\/code>, inline styles and custom <code>viewBox<\/code> values survive. WordPress 7.1's sanitizer only allows <code>&lt;svg&gt;<\/code>, <code>&lt;path&gt;<\/code> and <code>&lt;polygon&gt;<\/code> (no <code>stroke<\/code>, no inline styles) and therefore breaks many stroke-based icon sets.<\/li>\n<li>Reuse existing sprites: generate a sprite with svgforge-cli (sanitization + svgo optimization) and upload it \u2014 no per-icon PHP code required.<\/li>\n<li><strong>Need a sprite?<\/strong> Learn step by step how to build your own custom SVG icon set: <a href=\"https:\/\/svgforge.github.io\/blog\/posts\/custom-icon-sets\/\">Creating custom icon sets with svgforge-cli<\/a>.<\/li>\n<li>One file: the sprite is a single cacheable file that lives in the theme repo and is versioned with Git.<\/li>\n<li>Cache friendly: the sprite is one static SVG file, so the browser caches it once and every icon on the whole site reuses that cached file \u2014 no per-icon HTTP requests.<\/li>\n<li>Control per block: fill and stroke colours, size (standard Dimensions panel with preset slider + custom input), links with <code>rel<\/code> handling and aria-labels \u2014 per icon instance, without touching a stylesheet.<\/li>\n<li>Also runs on WordPress versions before 7.1 (from 6.6).<\/li>\n<\/ul>\n\n<p>Limitations you should know about:<\/p>\n\n<ul>\n<li>To add or change icons you have to rebuild the sprite file \u2014 typically with svgforge-cli, which handles sanitization and svgo optimization. There is no in-browser icon editor or management UI.<\/li>\n<li>The icons live in your content as a block. There is no replacement for the simple <code>wp_get_icon()<\/code> helper in theme PHP \u2014 that is what the native 7.1 approach is for.<\/li>\n<\/ul>\n\n<h4>Features<\/h4>\n\n<ul>\n<li>Settings page (Settings \u2192 SVG Forge Icon Manager) to upload the SVG sprite file \u2014 svgforge-cli handles full sanitization and svgo optimization, the plugin strips scripts, event handlers and <code>javascript:<\/code> links as a safety net.<\/li>\n<li>Theme override via the <code>sfim_sprite_url<\/code> filter (e.g. <code>get_theme_file_uri()<\/code>) \u2013 the filter has priority over everything.<\/li>\n<li>Symbol picker in the editor with a live preview of all icons from the sprite; icons from sprite subdirectories (IDs like <code>directory--filename<\/code>) are grouped and selectable via a filter in the dropdown.<\/li>\n<li>Icons can be linked (new tab + rel attributes including noopener\/noreferrer).<\/li>\n<li>Aria-label for screen readers; linked icons are automatically labelled via the link.<\/li>\n<li>Fill and stroke colour as well as size per block (square, preset slider + custom input with units).<\/li>\n<li>Fully dynamic server-side rendering (render.php) with <code>get_block_wrapper_attributes()<\/code>.<\/li>\n<li>Block supports: alignment, anchor, additional CSS classes.<\/li>\n<\/ul>\n\n<h4>Configure the sprite file<\/h4>\n\n<p>The SVG sprite file is resolved in this order (first existing source wins):<\/p>\n\n<ol>\n<li>Filter <code>sfim_sprite_url<\/code> \u2013 the canonical override (has priority).<\/li>\n<li>Uploaded file from Settings \u2192 SVG Forge Icon Manager (backend upload).<\/li>\n<li>Fallback: <code>sprite.svg<\/code> in the plugin directory.<\/li>\n<\/ol>\n\n<p>Override with a filter (recommended, versionable with the theme) in the theme's <code>functions.php<\/code>:<\/p>\n\n<pre><code>add_filter( 'sfim_sprite_url', fn () =&gt; get_theme_file_uri( 'assets\/ico.svg' ) );\n<\/code><\/pre>\n\n<p>or point it at a CDN:<\/p>\n\n<pre><code>add_filter( 'sfim_sprite_url', fn () =&gt; 'https:\/\/cdn.example.com\/icons\/ico.svg' );\n<\/code><\/pre>\n\n<p>SVG Forge Icon Manager is a developer-focused Gutenberg block that arranges a curated set of SVG icons as one central sprite and reuses them everywhere in your content. It works with any symbol sprite produced by modern build tools, is fully translated, and gives you precise control over colours, size, links and accessibility on every single block instance. The plugin prefers simplicity and performance: no tracking, no third-party requests, no page-weight overhead, and no vendor lock-in to a particular icon pack or service.<\/p>\n\n<h3>Development<\/h3>\n\n<p>Development is done on <a href=\"https:\/\/github.com\/svgforge\/sf-icon-manager\">GitHub<\/a>.<\/p>\n\n<!--section=installation-->\n<ol>\n<li>Upload the plugin folder to <code>\/wp-content\/plugins\/<\/code> (or install the ZIP via Plugins \u2192 Add New).<\/li>\n<li>Activate the plugin under \"Plugins\".<\/li>\n<li>Upload the sprite file (<code>ico.svg<\/code> with <code>&lt;symbol id=\"...\"&gt;<\/code> elements) via <strong>Settings \u2192 SVG Forge Icon Manager<\/strong> or reference your own file with the <code>sfim_sprite_url<\/code> filter.<\/li>\n<li>In the editor, add the \"SVG Icon\" block and choose an icon.<\/li>\n<\/ol>\n\n<!--section=faq-->\n<dl>\n<dt id=\"where%20do%20the%20icons%20come%20from%3F\"><h3>Where do the icons come from?<\/h3><\/dt>\n<dd><p>From the central sprite file <code>ico.svg<\/code>. Each icon is a <code>&lt;symbol id=\"my-icon\" viewBox=\"0 0 24 24\"&gt;\u2026&lt;\/symbol&gt;<\/code> element. The sprite is a static <a href=\"https:\/\/css-tricks.com\/svg-symbol-good-choice-icons\/\">SVG fragment<\/a> file that the browser loads as a regular SVG fragment.<\/p><\/dd>\n<dt id=\"why%20not%20simply%20use%20the%20native%20svg%20icons%20of%20wordpress%207.1%3F\"><h3>Why not simply use the native SVG icons of WordPress 7.1?<\/h3><\/dt>\n<dd><p>WordPress 7.1 offers a native icon system with <code>wp_register_icon_collection()<\/code> \/ <code>wp_register_icon()<\/code> \/ <code>wp_get_icon()<\/code> \u2014 that is enough if you register a few icons directly in code. This plugin complements that where a central SVG sprite is used: full SVG freedom (including stroke icons), existing sprites without per-icon PHP code, a single cacheable file and per-instance block styling. Since 0.2 the plugin can also register every symbol of that sprite as an <code>sf-icon-manager<\/code> collection (experimental), so the same sprite feeds the native Icon block and <code>wp_get_icon()<\/code> too \u2014 see the \"WordPress native icon integration\" setting.<\/p><\/dd>\n<dt id=\"does%20it%20work%20without%20js%20in%20the%20frontend%3F\"><h3>Does it work without JS in the frontend?<\/h3><\/dt>\n<dd><p>Yes. The frontend markup is generated server-side in <code>render.php<\/code>; the built JS is only needed in the editor.<\/p><\/dd>\n<dt id=\"how%20do%20i%20disable%20the%20color%20options%20for%20the%20block%3F\"><h3>How do I disable the color options for the block?<\/h3><\/dt>\n<dd><p>Put the block's color settings into your theme's <code>theme.json<\/code>:<\/p>\n\n<pre><code>{\n    \"version\": 3,\n    \"settings\": {\n        \"blocks\": {\n            \"sf-icon-manager\/svg-icon\": {\n                \"color\": { \"custom\": false, \"palette\": [] }\n            }\n        }\n    }\n}\n<\/code><\/pre>\n\n<p>That removes the standard Gutenberg Color\/Background panels for the SVG Icon block. As in the core Icon block, multi-color icons (e.g. Tango icon sets) keep their baked-in colors and are not affected by the color controls; monochrome icons follow the chosen color.<\/p><\/dd>\n<dt id=\"how%20do%20i%20offer%20preset%20sizes%20like%20font%20sizes%3F\"><h3>How do I offer preset sizes like font sizes?<\/h3><\/dt>\n<dd><p>The size is the standard Gutenberg Dimensions panel (<code>supports.dimensions.width<\/code>, like the core Icon block): the block is square, and size presets are standard theme.json <code>dimensionSizes<\/code> per block:<\/p>\n\n<pre><code>{\n    \"version\": 3,\n    \"settings\": {\n        \"blocks\": {\n            \"sf-icon-manager\/svg-icon\": {\n                \"dimensions\": {\n                    \"dimensionSizes\": [\n                        { \"name\": \"S\", \"slug\": \"s\", \"size\": \"32px\" },\n                        { \"name\": \"L\", \"slug\": \"l\", \"size\": \"64px\" }\n                    ],\n                    \"width\": true\n                }\n            }\n        }\n    }\n}\n<\/code><\/pre>\n\n<p>With presets the panel shows a slider that moves across the preset sizes, like the core Icon block. A toggle next to it switches to a custom value input with a slider, using the allowed units (<code>spacing.units<\/code>). <code>dimensions.width: false<\/code> disables sizing entirely, so the block always renders at its default size.<\/p><\/dd>\n\n<\/dl>\n\n<!--section=changelog-->\n<h4>0.3.4<\/h4>\n\n<ul>\n<li>Readme: clarified that the sprite is a static SVG fragment file loaded by the browser via <code>&lt;use&gt;<\/code> (no JS on the frontend), added the custom icon sets tutorial link and a \"Cache friendly\" selling point.<\/li>\n<li>High-resolution plugin screenshot.<\/li>\n<\/ul>\n\n<h4>0.3.3<\/h4>\n\n<ul>\n<li><code>Tested up to: 7.1<\/code> (wp.org plugin check rejects minor versions).<\/li>\n<\/ul>\n\n<h4>0.3.2<\/h4>\n\n<ul>\n<li>Admin stylesheet enqueued via <code>wp_enqueue_style<\/code>.<\/li>\n<li><code>composer.json<\/code> ships in the plugin ZIP (required when <code>vendor\/<\/code> exists).<\/li>\n<li>Test suite upgraded to WordPress 7.1.1 with PHPUnit 12.<\/li>\n<\/ul>\n\n<h4>0.3.1<\/h4>\n\n<ul>\n<li>Admin UI branded as \"SVG Forge Icon Manager\" (settings menu, page title, native icons collection label); translations regenerated.<\/li>\n<li><code>\/i.svg<\/code> no longer cached immutably: the local-file branch revalidates on every request (<code>no-cache, must-revalidate<\/code>) with real <code>304 Not Modified<\/code> responses, so sprite changes are picked up immediately.<\/li>\n<li>TypeScript sources, test files and type declarations no longer ship in the production plugin ZIP.<\/li>\n<\/ul>\n\n<h4>0.3.0<\/h4>\n\n<ul>\n<li>Short URL <code>\/i.svg<\/code> for the sprite, opt-in via the <code>sfim_short_url<\/code> filter.<\/li>\n<li>Stricter upload sanitization (allowlist via enshrined\/svg-sanitize instead of regex); automated dev releases from <code>main<\/code>; the plugin ZIP ships its vendored dependencies.<\/li>\n<li>Type declarations across the source (PHP 8.3+); padding applies to the SVG element, not the wrapper.<\/li>\n<li>New <code>docs\/api.md<\/code> API reference; settings page shows the short URL under \"Active sprite file\".<\/li>\n<\/ul>\n\n<h4>0.2.1<\/h4>\n\n<ul>\n<li>wp.org compliance: escaped SVG output with an input allowlist, direct-access guard in the render template, readme and changelog cleanup.<\/li>\n<li>Remove the now-discouraged <code>load_plugin_textdomain()<\/code> call; WordPress loads translations for the plugin slug automatically.<\/li>\n<\/ul>\n\n<h4>0.2.0<\/h4>\n\n<ul>\n<li>WordPress 7.1 native icon integration (experimental): symbols of the configured sprite are registered as an <code>sf-icon-manager<\/code> icon collection (setting \"WordPress native icon integration\", default Off).<\/li>\n<li>New setting mode \"Off + disable core Icon block\" deregisters the built-in Icon block in the editor (including in content) and its frontend rendering.<\/li>\n<li>Registration is lazy: it only runs when needed (core Icon block or REST), keeping page-load cost independent of the icon count.<\/li>\n<\/ul>\n\n<h4>0.1.0<\/h4>\n\n<ul>\n<li>Initial release.<\/li>\n<\/ul>","raw_excerpt":"SVG Icon Block: inserts icons from your own SVG sprite via , can link them. For developers who maintain their sprite file with CLI tools.","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/arg.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin\/369199","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/arg.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin"}],"about":[{"href":"https:\/\/arg.wordpress.org\/plugins\/wp-json\/wp\/v2\/types\/plugin"}],"replies":[{"embeddable":true,"href":"https:\/\/arg.wordpress.org\/plugins\/wp-json\/wp\/v2\/comments?post=369199"}],"author":[{"embeddable":true,"href":"https:\/\/arg.wordpress.org\/plugins\/wp-json\/wporg\/v1\/users\/wpdynamics"}],"wp:attachment":[{"href":"https:\/\/arg.wordpress.org\/plugins\/wp-json\/wp\/v2\/media?parent=369199"}],"wp:term":[{"taxonomy":"plugin_section","embeddable":true,"href":"https:\/\/arg.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_section?post=369199"},{"taxonomy":"plugin_tags","embeddable":true,"href":"https:\/\/arg.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_tags?post=369199"},{"taxonomy":"plugin_category","embeddable":true,"href":"https:\/\/arg.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_category?post=369199"},{"taxonomy":"plugin_contributors","embeddable":true,"href":"https:\/\/arg.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_contributors?post=369199"},{"taxonomy":"plugin_business_model","embeddable":true,"href":"https:\/\/arg.wordpress.org\/plugins\/wp-json\/wp\/v2\/plugin_business_model?post=369199"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}