Adding SVG Icons to a Redmine 6+ Plugin
Redmine 6+ has switched to using SVG sprites for icons instead of traditional PNGs. This improves performance, reduces the number of HTTP requests, and simplifies icon management.
This document explains how to correctly add SVG icons to a plugin, following Redmine's official recommendations.
1. Using Standard Redmine Icons¶
Before adding custom icons to a plugin, it is recommended to use the built-in Redmine SVG icons.
This can be done using the sprite_icon
method:
<%= sprite_icon('pencil', l(:button_edit)) %>
<%= sprite_icon('plus', l(:button_add)) %>
<%= sprite_icon('trash', l(:button_delete)) %>
This method automatically uses icons.svg
from Redmine.
Important! Some icons, such as add, delete, copy, edit, already exist in Redmine’s global sprite. These should be used without specifying the plugin to avoid duplication:
<%= sprite_icon('add', l(:button_add)) %>
<%= sprite_icon('delete', l(:button_delete)) %>
<%= sprite_icon('copy', l(:button_copy)) %>
If the plugin
parameter is specified, Redmine will look for these icons in the plugin sprite, even though they already exist in Redmine's default set, making their recreation unnecessary.
2. Adding Custom Icons to a Plugin¶
Step 1: Creating config/icon_source.yml
¶
To use additional icons, create the config/icon_source.yml
file inside the plugin folder.
This file allows downloading SVG icons from Tabler Icons and automatically including them in the sprite.
Example config/icon_source.yml
:
# This file is used by icons rake task to download SVG icons from Tabler
# Keys description:
# - name: destination icon name (used in sprite_icon)
# svg: source icon name from Tabler Icons
# style: outline (default) or filled
- name: custom-icon
svg: star
- name: reload
svg: refresh
- name — the icon name used in sprite_icon
.
- svg — the original icon name from Tabler Icons.
- style — an optional parameter (outline
or filled
).
Step 2: Generating icons.svg
for the Plugin¶
After setting up config/icon_source.yml
, run the following command:
rake icons:plugin:generate NAME=<redmine_plugin_name>
This command:
- Downloads the required icons from Tabler Icons.
- Creates
icons.svg
inpublic/plugin_assets/<redmine_plugin_name>/images/
. - Generates an SVG sprite that can be used in templates.
After running the command, check the contents of icons.svg
and manually edit it if needed.
Step 3: Using Custom Icons in Templates¶
After generating icons.svg
, icons can be used in plugin templates:
<%= sprite_icon('custom-icon', plugin: :<redmine_plugin_name>) %>
<%= sprite_icon('reload', plugin: :<redmine_plugin_name>) %>
Important! The plugin
parameter should be used only for custom icons that are not included in Redmine’s default set.
3. CSS Rules for PNG Icon Compatibility¶
For backward compatibility with CSS classes that used PNG files, update the CSS.
Use :not(:has(svg))
to ensure PNGs are only displayed when an SVG is unavailable.
Example app/assets/stylesheets/<redmine_plugin_name>.css
:
.icon-edit:not(:has(svg)) { background-image: url(../images/pencil.png); }
.icon-add:not(:has(svg)) { background-image: url(../images/circle-plus.png); }
.icon-copy:not(:has(svg)) { background-image: url(../images/copy.png); }
.icon-del:not(:has(svg)) { background-image: url(../images/trash.png); }
If the browser does not support :has()
, use JavaScript to remove background-image
from elements containing <svg>
:
document.querySelectorAll('.icon').forEach(icon => {
if (icon.querySelector('svg')) {
icon.style.backgroundImage = 'none';
}
});
4. Additional Rake Tasks for Icon Management¶
Command | Description |
---|---|
rake icons:download |
Downloads Redmine's default icons |
rake icons:generate |
Downloads icons and generates an SVG sprite |
rake icons:plugin:download |
Downloads SVG icons for a plugin |
rake icons:plugin:generate |
Downloads icons and generates a sprite for a plugin |
rake icons:plugin:sprite |
Generates only a sprite for the plugin |
rake icons:sprite |
Generates a general SVG sprite |
Use rake icons:plugin:generate NAME=<redmine_plugin_name>
to update the sprite.
5. Support for Older Versions of Redmine¶
For backward compatibility with Redmine 5 and earlier, where sprite_icon
may be missing, use a compatibility patch from redmineup
gem.
Adding Compatibility in init.rb
¶
require 'redmineup/patches/compatibility_patch'
This patch automatically adapts icon handling for older versions of Redmine.
6. Common Errors and Solutions¶
Error | Solution |
---|---|
Icon does not display | Ensure that plugin: :<redmine_plugin_name> is specified in sprite_icon if using a custom plugin icon. |
Icon was not added to icons.svg |
Check that config/icon_source.yml contains valid entries and rerun rake icons:plugin:generate . |
Changes to icons.svg are not applied |
Run rake assets:precompile to rebuild assets. |
Old PNG icons are still displayed | Add :not(:has(svg)) to CSS to disable background-image when an SVG is present. |
Conclusion¶
- Use standard Redmine icons without
plugin
to avoid duplication. - Create
config/icon_source.yml
and define custom icons. - Generate
icons.svg
usingrake icons:plugin:generate
. - Use
sprite_icon('custom-icon', plugin: :<redmine_plugin_name>)
only for new icons. - Add a CSS filter
:not(:has(svg))
to disable old PNG icons. - Rebuild assets using
rake assets:precompile
. - For compatibility, include
compatibility_patch
.
Following these recommendations will ensure correct SVG icon rendering in your plugin and maintain compatibility with Redmine 6+.