We will shortly merge into master
a branch that upgrades Discourse to Font Awesome 5.5.0 (the free version) and switches to using SVG icons instead of an icon font. This is a substantial change, with lots of benefits, and one significant change for developers.
Here is a quick rundown of the changes:
- using SVG icons will provide crisper icons, better for accessibility and easier to customize, see this Github article for more details
- since the Font Awesome icon set has grown to 1300+ icons in version 5, we have built an internal API that delivers to clients a subset of all FA icons, that is, only those icons used by that Discourse instance
- the subset thankfully has a smaller size footprint: itās already running here in Meta, and it is only 27.5 kb vs the 75.7 kb of the FA 4.7 icon font
- plugins and themes (including theme components) can add additional FA icons to the set
- group flair and badge icons will automatically be included in the set, and site administrators can also use a new site setting called
svg icon subset
to register their chosen icons and add them to their siteās subset - breaking change: plugin and theme developers can no longer use
<i class="fa fa-icon"></i>
or override the:before
pseudo selectors to reference/replace icons, these should now be replaced by using Discourse functions that inject SVGs in the page
Below, you can find instructions on how to update plugins and themes to use icons from the new set.
Whatās new in Font Awesome 5
Font Awesome 5 has introduced many new icons but also some naming changes. For a full discussion of the changes please see the Font Awesome upgrade documentation. The main change is that icons in FA come in separate styles now. There are three styles:
- solid (default) ā
fas
- regular ā
far
- brands ā
fab
For the regular or brands styles, FA 5 introduces new class prefixes, āfarā and āfabā respectively. To use an icon from the regular or brands styles, then, we need to use this new naming convention: "far fa-address-book"
or "fab fa-facebook"
. (Solid icons can simply be referenced as before āfa-icon-nameā).
To allow bundling the three styles into one SVG sprite, icons in the regular and brand styles in Discourse are converted to far-icon-name
and fab-icon-name
internally. Plugins, themes, group flair and badges can use the standard FontAwesome 5 naming convention. Site admins adding icons to the set via the svg icon subset
site setting must use the internal naming convention.
Developers: how to use or add an SVG icon to your plugin or theme
-
Adding new icons
plugins:
register the icon in your pluginās
plugin.rb
file:register_svg_icon "user-times" if respond_to?(:register_svg_icon)
(Note: you need to restart your Rails server in your development environment for this change to take effect.)
themes or components:
add a string or list setting with a name containing
_icon
, for example:svg_icons: default: 'question-circle|wallet' type: 'list' list_type: 'compact'
and Discourse will include the icon(s) defined in that theme setting to the subset.
-
Using icons in your javascript
plugins:
import { iconNode } from "discourse-common/lib/icon-library"; ... let icon = iconNode('user-times');
or use the
iconHTML
helperimport { iconHTML } from "discourse-common/lib/icon-library"; ... let icon = iconHTML('user-times');
themes or components:
const { iconNode } = require("discourse-common/lib/icon-library"); ... let icon = iconNode('user-times');
or use the
iconHTML
helperconst { iconHTML } = require("discourse-common/lib/icon-library"); ... let icon = iconHTML('user-times');
the helpers can also take a second parameter with properties like title or class. This works in plugins and themes / components in the same way, for example
iconHTML('user-times', { class: "reply-to-glyph" })
-
Using icons in your handlebars templates
In Handlebars templates, you can used-icon
, like this:{{d-icon 'user-times'}}
this also works in the same way for plugins and themes / components
Adding custom icons
If you would like to have more icons than whatās available in FontAwesome, you can add your own SVG icons in a plugin or a theme. See this SVG sprite for an example of how to structure your sprite. (Itās essentially a list of <symbol>
elements, each with its own unique ID.)
In themes and components: add the SVG sprite in the /assets
folder, and reference it in about.json
using the variable name icons-sprite
. For a sprite called my-icons.svg
, your assets.json should include this:
"assets": {
"icons-sprite": "/assets/my-icons.svg"
}
You can also add the SVG sprite to a theme or component via the UI, when doing so, make sure the SCSS var name is set to icons-sprite
. Screenshot:
In plugins: simply include an SVG sprite file in the plugins/your-plugin-name/svg-icons
folder. Restart your server (if in dev) or rebuild the site if in a Docker container and your custom icons should be automatically available.
To avoid any potential clashes with FontAwesome icon ids, you should prefix the ids of the custom icons in your plugin or theme.