Symfony UX Icons
The symfony/ux-icons
package offers simple and intuitive ways to render
SVG icons in your Symfony application. It provides a Twig function to include
any local or remote icons from your templates.
UX Icons gives you a direct access to over 200,000 vector icons from popular icon sets such as FontAwesome, Bootstrap Icons, Tabler Icons, Google Material Design Icons, etc.
Installation
1
$ composer require symfony/ux-icons
SVG Icons
SVG (Scalable Vector Graphics) is an XML-based vector image format, allowing resolution-independent graphics while maintaining a small file size. SVG icons can be embedded in the HTML code, styled with CSS, and animated with JavaScript.
UX Icons allows you to use icons from the most popular icon sets, but also gives you the flexibility to compose your own collection, mixing icons from different sets with your own.
Icon Names
Icons are referenced using an unique identifier that follows one of the following syntaxes:
prefix:name
(e.g.mdi:check
,bi:check
,editor:align-left
)name
only (e.g.check
,close
,menu
)
The icon name
is the same as the file name without the file extension (e.g. check.svg
-> check
).
Caution
The name must match a standard slug
format: [a-z0-9-]+(-[0-9a-z])+
.
Depending on your configuration, the prefix
can be the name of an icon set, a directory
where the icon is located, or a combination of both.
For example, the bi
prefix refers to the Bootstrap Icons set, while the header
prefix
refers to the icons located in the header
directory.
Loading Icons
1 2 3 4 5 6 7 8 9 10
{# includes the contents of the 'assets/icons/user-profile.svg' file in the template #}
{{ ux_icon('user-profile') }}
{# icons stored in subdirectories must use the 'subdirectory_name:file_name' syntax
(e.g. this includes 'assets/icons/admin/user-profile.svg') #}
{{ ux_icon('admin:user-profile') }}
{# this downloads the 'user-solid.svg' icon from the 'Flowbite' icon set via ux.symfony.com
and embeds the downloaded SVG contents in the template #}
{{ ux_icon('flowbite:user-solid') }}
Note
To search and download icons via ux.symfony.com/icons, the symfony/http-client
package must be installed in your application:
1
$ composer require symfony/http-client
The ux_icon()
function defines a second optional argument where you can
define the HTML attributes added to the <svg>
element:
1 2 3 4 5
{{ ux_icon('user-profile', {class: 'w-4 h-4'}) }}
{# renders <svg class="w-4 h-4"> ... </svg> #}
{{ ux_icon('user-profile', {height: '16px', width: '16px', 'aria-hidden': true}) }}
{# renders <svg height="16" width="16" aria-hidden="true"> ... </svg> #}
Icon Sets
There are many icon sets available, each with their own unique style and set of icons, providing a wide range of icons for different purposes, while maintaining a consistent look and feel across your application. Here are some of the most popular icon sets available:
Icon Set | Icons | License | Prefix | Example |
---|---|---|---|---|
Bootstrap Icons | 2000 | MIT | bi |
bi:check |
Boxicons | 1700 | MIT | bx |
bx:check |
Flowbite | 1000 | MIT | flowbite |
flowbite:check |
FontAwesome Icons | 7000 | CC BY 4.0 | fa6-regular |
fa6-regular:check |
Heroicons | 300 | MIT | heroicons |
heroicons:check |
Iconoir | 1500 | MIT | iconoir |
iconoir:check |
Ionicons | 1300 | MIT | ion |
ion:check |
Lucide Icons | 1500 | MIT | lucide |
lucide:check |
Material Design Icons | 5000 | Apache 2 | mdi |
mdi:check |
Octicons | 600 | MIT | octicon |
octicon:check |
Phosphor Icons | 7000 | MIT | ph |
ph:check |
Tabler Icons | 5200 | MIT | tabler |
tabler:check |
To see the full list of available icon sets, visit ux.symfony.com/icons.
Search Icon sets
You can use the ux:icons:search
command to search for icon sets, or to find
the prefix of a specific icon set:
1 2 3 4 5 6 7 8 9 10 11
$ php bin/console ux:icons:search tabler
-------------- ------- --------- -------- --------------
Icon set Icons License Prefix Example
-------------- ------- --------- -------- --------------
Tabler Icons 5219 MIT tabler tabler:alien
-------------- ------- --------- -------- --------------
Search "arrow" in Tabler Icons icons:
php bin/console ux:icons:search tabler arrow
Search Icons
You can also search for icons within a specific icon set. To search for "arrow" icons in the "Tabler Icons" set, use the following command:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
$ php bin/console ux:icons:search tabler arrow
Searching Tabler Icons icons "arrow"...
Found 64 icons.
------------------------------------------ ------------------------------------------
tabler:archery-arrow tabler:arrow-autofit-up
tabler:arrow-back tabler:arrow-back-up
tabler:arrow-badge-down tabler:arrow-badge-up
tabler:arrow-badge-up-filled tabler:arrow-bar-both
tabler:arrow-bar-down tabler:arrow-bar-left
tabler:arrow-bar-right tabler:arrow-bar-to-up
tabler:arrow-bar-up tabler:arrow-bear-left
tabler:arrow-big-down tabler:arrow-big-down-filled
tabler:arrow-big-down-line tabler:arrow-big-left
tabler:arrow-big-left-filled tabler:arrow-big-left-line
tabler:arrow-big-right tabler:arrow-big-right-filled
tabler:arrow-big-right-line tabler:arrow-big-up
------------------------------------------ ------------------------------------------
Page 1/3. Continue? (yes/no) [yes]:
>
HTML Syntax
In addition to the ux_icon()
function explained in the previous sections,
this package also supports an alternative HTML syntax based on the <twig:ux:icon>
tag:
1 2 3 4 5 6 7 8 9
<!-- renders "user-profile.svg" -->
<twig:ux:icon name="user-profile" class="w-4 h-4" />
<!-- renders "admin/user-profile.svg" -->
<twig:ux:icon name="admin:user-profile" class="w-4 h-4" />
<!-- renders 'user-solid.svg' icon from 'Flowbite' icon set via ux.symfony.com -->
<twig:ux:icon name="flowbite:user-solid" />
<!-- you can also add any HTML attributes -->
<twig:ux:icon name="user-profile" height="16" width="16" aria-hidden="true" />
Tip
To use the HTML syntax, the symfony/ux-twig-component
package must be
installed in your project.
Downloading Icons
This package doesn't include any icons, but provides access to over 200,000 open source icons.
Local SVG Icons
If you already have the SVG icon files to use in your project, store them in the
assets/icons/
directory and commit them. The name of the file is used as the
name of the icon (icon_name.svg
will be named icon_name
). If located in
a subdirectory, the name will be subdirectory:icon_name
.
1 2 3 4 5 6 7 8 9 10 11 12 13
your-project/
├─ assets/
│ └─ icons/
│ ├─ bi/
│ │ └─ pause-circle.svg
│ │ └─ play-circle.svg
│ ├─ header/
│ │ ├─ logo.svg
│ │ └─ menu.svg
│ ├─ close.svg
│ ├─ menu.svg
│ └─ ...
└─ ...
Icons On-Demand
ux.symfony.com/icons has a huge searchable repository of icons from many different sets. This package provides a way to include any icon found on this site on-demand:
- Visit ux.symfony.com/icons and search for an icon you'd like to use. Once you find one you like, copy one of the code snippets provided.
- Paste the snippet into your Twig template and the icon will be automatically fetched (and cached).
That's all. This works by using the Iconify API (to which ux.symfony.com/icons is a frontend for) to fetch the icon and render it in place. This icon is then cached for future requests for the same icon.
Note
Local SVG Icons of the same name will have precedence over on-demand icons.
Importing Icons
While on-demand icons are great during development, they require HTTP requests to fetch the icon and always use the latest version of the icon. It's possible that the icon could change or be removed in the future. Additionally, the cache warming process will take significantly longer if using many on-demand icons.
That's why this package provides a command to download the open source icons into
the assets/icons/
directory. You can think of importing an icon as locking it
(similar to how composer.lock
locks your dependencies):
1 2 3 4 5 6
# icon will be saved in `assets/icons/flowbite/user-solid.svg` and you can
# use it with the name: `flowbite:user-solid`
$ php bin/console ux:icons:import flowbite:user-solid
# it's also possible to import several icons at once
$ php bin/console ux:icons:import flowbite:user-solid flowbite:home-solid
Note
Imported icons must be committed to your repository.
Locking On-Demand Icons
You can lock (import) all the on-demand icons you're using in your project by running the following command:
1
$ php bin/console ux:icons:lock
This command only imports icons that do not already exist locally. You can force
the report to overwrite existing icons by using the --force
option:
1
$ php bin/console ux:icons:lock --force
Rendering Icons
1 2 3 4 5 6 7 8 9 10
{# includes the contents of the 'assets/icons/user-profile.svg' file in the template #}
{{ ux_icon('user-profile') }}
{# icons stored in subdirectories must use the 'subdirectory_name:file_name' syntax
(e.g. this includes 'assets/icons/admin/user-profile.svg') #}
{{ ux_icon('admin:user-profile') }}
{# this downloads the 'user-solid.svg' icon from the 'Flowbite' icon set via ux.symfony.com
and embeds the downloaded SVG contents in the template #}
{{ ux_icon('flowbite:user-solid') }}
HTML Syntax
1 2 3 4 5 6 7 8 9 10
<twig:ux:icon name="user-profile" />
{# Renders "user-profile.svg" #}
<twig:ux:icon name="user-profile" class="w-4 h-4" />
{# Renders "sub-dir/user-profile.svg" (sub-directory) #}
<twig:ux:icon name="sub-dir:user-profile" class="w-4 h-4" />
{# Renders "flowbite:user-solid" from ux.symfony.com #}
<twig:ux:icon name="flowbite:user-solid" />
Note
symfony/ux-twig-component
is required to use the HTML syntax.
Default Attributes
You can set default attributes for all icons in your configuration. These attributes will be
added to all icons unless overridden by the second argument of the ux_icon
function.
1 2 3 4
# config/packages/ux_icons.yaml
ux_icons:
default_icon_attributes:
fill: currentColor
Now, all icons will have the fill
attribute set to currentColor
by default.
1 2 3 4 5
# renders "user-profile.svg" with fill="currentColor"
{{ ux_icon('user-profile') }}
# renders "user-profile.svg" with fill="red"
{{ ux_icon('user-profile', {fill: 'red'}) }}
Icon Aliases
2.20
Icon Aliases feature was added in 2.20.
Aliases are custom names you can define to refer to any icon. They are useful for creating shortcuts to icons you frequently use in your templates:
1 2 3 4 5
# config/packages/ux_icons.yaml
ux_icons:
# ...
aliases:
dots: 'clarity:ellipsis-horizontal-line'
Now, you can use the dots
alias in your templates:
1 2 3 4 5 6 7 8
{{ ux_icon('dots') }}
{# with the previous configuration, this is the same as: #}
{{ ux_icon('clarity:ellipsis-horizontal-line') }}
{# using the HTML syntax #}
<twig:ux:icon name="dots" />
{# same as: #}
<twig:ux:icon name="clarity:ellipsis-horizontal-line" />
Errors
If an icon is not found, an exception is thrown. This is useful during development,
but in production, you may want to render an error message instead. You can do this
by setting the ignore_not_found
configuration option to true
:
1 2 3
# config/packages/ux_icons.yaml
ux_icons:
ignore_not_found: true
Accessibility
Icons add visual elements to your website and they can be a challenge for accessibility. According to the W3C guide about SVG icon accessibility, there are three methods to improve icons accessibility, depending on the context.
- Informative icons
-
They convey information or a function. They should define a text alternative that presents the same content or function via the
aria-label
attribute used by screen readers and other assistive technologies:1 2
Today's weather: {{ ux_icon('cloud-rain', {'aria-label': 'Rainy weather'}) }}
- Functional icons
-
They are interactive and perform a function. They should define a text alternative that presents the same content or function via the
aria-label
attribute used by screen readers and other assistive technologies:1
{{ ux_icon('user-profile', {class: 'w-4 h-4', 'aria-label': 'User Profile'}) }}
- Decorative icons
-
They are purely decorative and do not convey any meaning or function. They should be hidden from screen readers using the
aria-hidden
attribute.1 2 3 4 5 6
<a href="/profile"> <svg viewBox="0 0 24 24" class="w-4 h-4" aria-hidden="true"> <!-- ... --> </svg> Back to profile </a>
That is why the ux_icon()
function and the <twig:ux:icon>
component add
aria-hidden="true"
attribute automatically to icons not having at least one
of the following attributes: aria-label
, aria-labelledby
or title
.
Note
If you don't want to set aria-hidden="true"
for a specific icon, you can
explicitly set the aria-hidden
attribute to false
:
1
<twig:ux:icon name="user-profile" aria-hidden="false" />
Performance
The UX Icons component is designed to be fast. The following are some of the optimizations made to ensure the best performance possible.
Caching
On-Demand VS Import
While on-demand icons are great during development, they require HTTP requests to fetch the icon
and always use the latest version of the icon. It's possible the icon could change or be removed
in the future. Additionally, the cache warming process will take significantly longer if using
many _on-demand_ icons. You can think of importing the icon as locking it (similar to how
composer.lock
_locks_ your dependencies).
Icon Caching
To avoid having to parse icon files on every request, icons are cached. In production, you can pre-warm the cache by running the following command:
1
$ php bin/console ux:icons:warm-cache
This command looks in all your Twig templates for ux_icon()
calls and
<twig:ux:icon>
tags and caches the icons it finds.
Caution
Icons that have a name built dynamically will not be cached. It's advised to have the icon name as a string literal in your templates.
1 2 3 4 5 6 7 8 9
{# This will be cached #}
{{ ux_icon('flag-fr') }}
{# This will NOT be cached #}
{{ ux_icon('flag-' ~ locale) }}
{# in this example, both "flag-fr" and "flag-de" will be cached #}
{% set flags = {fr: 'flag-fr', de: 'flag-de'} %}
{{ ux_icon(flags[locale]) }}
Note
During development, if you modify an icon, you will need to clear the cache
(bin/console cache:clear
) to see the changes.
Tip
If using symfony/asset-mapper, the cache is warmed automatically when running asset-map:compile
.
TwigComponent
The ux_icon()
function is optimized to be as fast as possible. To deliver the
same level of performance when using the HTML syntax (<twig:ux:icon name="..." />
),
the TwigComponent overhead is reduced by calling the IconRenderer immediately and
returning the HTML output.
Warning
The <twig:ux:icon> component does not support embedded content.
1 2 3 4 5 6 7
{# The 🧸 will be ignored in the HTML output #}
<twig:ux:icon name="user-profile" class="w-4 h-4">🧸</twig:ux:icon>
{# Renders "user-profile.svg" #}
<svg viewBox="0 0 24 24" class="w-4 h-4">
<path fill="currentColor" d="M21 7L9 19l-5.5-5.5l1.41-1.41L9 16.17L19.59 5.59z"/>
</svg>
Configuration
The UX Icons integrates seamlessly in Symfony applications. All these options are configured under
the ux_icons
key in your application configuration.
1 2 3
# config/packages/ux_icons.yaml
ux_icons:
{# ... #}
Debugging Configuration
1 2 3 4 5
# Displays the default config values
$ php bin/console config:dump-reference ux_icons
# Displays the actual config values used by your application
$ php bin/console debug:config ux_icons
Full Configuration
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27
# config/packages/ux_icons.yaml
ux_icons:
# The local directory where icons are stored
icon_dir: '%kernel.project_dir%/assets/icons'
# Default attributes to add to all icons
default_icon_attributes:
fill: currentColor
'font-size': '1.25em'
# Icon aliases (alias => icon name)
aliases:
dots: 'clarity:ellipsis-horizontal-line'
'tabler:save': 'tabler:device-floppy'
# Configuration for the "on demand" icons powered by Iconify.design
iconify:
enabled: true
# Whether to use the "on demand" icons powered by Iconify.design
on_demand: true
# The endpoint for the Iconify API
endpoint: 'https://api.iconify.design'
# Whether to ignore errors when an icon is not found
ignore_not_found: false