Icon API

Last updated on
16 December 2025

This documentation needs review. See "Help improve this page" in the sidebar.

Drupal 11.1 introduce the new Icon API dedicated to allow modules and themes to define icon packs.
Within each pack is a series of icons each with a unique identifier that the system can then use.
Modules and themes can alter icon packs.

How to add an icon pack

To declare an icon pack, simply create a EXTENSION_NAME.icons.yml file in the extension's base folder (theme or module). Each top-level entry in this YAML file defines a new icon pack, as a plugin with YAML discovery.

The YAML value config > sources can be used to inform about the location of the physical icons in your Drupal installation. Recommended is in libraries folder for generic icon packs that can be installed and updated with a package manager or in your theme or module for your own icons.

An icon pack must have an extractor, which can take values path, svg or svg_sprite. Contrib modules can add more extractors.

The icon pack json definition can be found in Drupal core > assets schemas.

Icon pack within themes

Some themes provide icons out of the box leveraging the API:

Icon pack declaration examples

See YAML icon pack declaration documentation for details on each available keys.

Simple with path and wildcard

fixed_path:
  extractor: path
  config:
    sources:
      - icons/*.svg
      - /libraries/icons/*.svg
  template: '<img src="{{ source }}" width="32" height="32" alt="{{ icon_id }}">'

Simple with svg, settings and wildcard

svg:
  label: SVG icons
  extractor: svg
  config:
    sources:
      - icons/*.svg
  settings:
    size:
      title: "Size"
      type: "integer"
      default: 32
    color:
      title: "Color"
      type: "string"
      format: "color"
  template: >-
    <svg
      {{ attributes
          .setAttribute('viewBox', attributes.viewBox|default('0 0 50 50'))
          .setAttribute('width', size|default('32'))
          .setAttribute('height', size|default('32'))
          .setAttribute('fill', color|default('currentColor'))
          .setAttribute('aria-hidden', 'true')
      }}
    >
      {{ content }}
    </svg>

Simple with SVG sprite file

svg_sprite:
  label: SVG sprite icons
  extractor: svg_sprite
  config:
    sources:
      - icons/foo_sprite.svg
  settings:
    size:
      title: "Size"
      type: "integer"
      default: 32
  template: >-
    <svg
      xmlns="https://www.w3.org/2000/svg"
      width="{{ size|default(32) }}"
      height="{{ size|default(32) }}"
      aria-hidden="true"
    >
      <use href="{{ source }}#{{ icon_id }}"/>
    </svg>

Advanced with metadata

wildcard_path:
  # Implicit is always enabled, if false will not be available.
  enabled: true
  label: Wildcards
  description: Icons from wildcard path
  links:
    - https://www.drupal.org
  version: 1.0.0
  license:
    name: GPL-3.0-or-later
    url: https://www.gnu.org/licenses/gpl-3.0.html
    gpl-compatible: true
  # Mandatory values to discover icons.
  extractor: path
  config:
    sources:
      - icons/*.png
      - icons/{group}/*.png
      - icons/*/{group}/*.png
      - icons/extracted/prefix_{icon_id}_suffix.png
  settings:
    width:
      title: "Width"
      type: "integer"
      default: 32
    height:
      title: "Height"
      type: "integer"
      default: 32
    alt:
      title: "Alt text"
      type: "string"
      description: "Accessibility alternative text, leave empty for decorative icon."
  template: >-
    <img
      class="icon icon-{{ icon_id|clean_class }}"
      src="{{ source }}"
      width="{{ width|default(32) }}"
      height="{{ height|default(32) }}"
      alt="{{ icon_id }}"
    >

See core/lib/Drupal/Core/Theme/Icon/Plugin/IconPackManager.php in the code-base for extended documentation of the various keys and their values.
As well as test examples in core/modules/system/tests/modules/icon_test/icon_test.icons.yml.

Icon pack external examples

An external GitLab repository include examples of Icon packs declarations for UI Icons contrib modules.

YAML icon pack declaration documentation

The `extractor` key

Drupal core provide common extractors to handle icons as images of format PNG, GIF, SVG and SVG Sprite.

These extractors require a config > sources array to indicate the physical path(s) or url(s) to the icons.
Url must simply be the direct access to the Icon, only http(s) is allowed.

Path extractor `path`

The extractor path within class PathExtractor provide a way to add local or remote images.
Images of types svg, png, gif are allowed, other formats will be ignored.

Path extractor will allow to create a Twig template using key template with variables:

  • source: The local path to the file within Drupal or the Url for remote file
  • icon_id: The Icon id based on the name of the file
  • group: Optional metadata if set in the config > sources to be extracted from the path, not available for remote files
  • ... Any other variable from settings definition or extractor, see settings key explanation

SVG extractor `svg`

The extractor svg within class SvgExtractor provide a way to handle and render SVG files.
Difference with path is that this extractor will read and rewrite the SVG content, for security concern, only local SVG files are allowed.

SVG extractor will allow to create a Twig template using key template with variables:

  • content: The svg file markup without <svg> parent element
  • attributes: The Drupal Attributes object populated with the original SVG files attributes existing in the <svg> element.
    For example if original svg file is <svg viewBox="0 0 50 50" class="foo">...</svg>, the attributes variable will have viewbox and class set.
  • icon_id: The Icon id based on the name of the file
  • group: Optional metadata if set in the config > sources to be extracted from the path
  • ... Any other variable from settings definition or extractor, see settings key explanation

SVG Sprite extractor `svg_sprite`

The extractor svg_sprite within class SvgSpriteExtractor provide a way to handle and render SVG Sprite file.
Difference with svg is that  this extractor will read and discover each icon from each SVG file(s) looking for element <symbol>, the content of each symbol will not be read and content variable is not available.

Difference with path is that this extractor will read and rewrite the SVG content, for security concern, only local SVG files are allowed.

SVG Sprite extractor will allow to create a Twig template using key template with variables:

  • source: The local path to the file within Drupal or the Url for remote file
  • icon_id: The Icon id based on the name of the file
  • group: Optional metadata if set in the config > sources to be extracted from the path, not available for remote files
  • ... Any other variable from settings definition or extractor, see settings key explanation

The recommended way of integrating the sprite is to use <use href="{{ source }}#{{ icon_id }}"/> in the template.

The `config` key

Most common usage for the config key is to set a sources array value to give a path to the icons to be discovered. This is needed for core extractors. The extractor class can then use it to return the list of discovered icons.

All config values are passed to the extractor, this is useful for custom extractors to have any needed configuration data.

The `config > sources` key

Sources is used to inform the extractor of path(s) or url(s) to discover the list of icons available in Drupal.

The path(s) will not be discovered recursively, it can include wildcard * in any part of the path.

If the path do not start with a slash /, it will resolve to the module or theme, else it will resolve to Drupal web root.

config:
  sources:
    - assets/icons/*.svg # relative to the YAML file module or theme
    - icons/*/*.svg # relative to the YAML file module or theme
    - icons/* # relative to the YAML file module or theme, all png, svg and gif
    - /libraries/my-icons/*.svg # absolute to Drupal installation folder
    - http://www.my_domain.com/my_icon.png

For path(s), it can include the keyword {icon_id} to identify and extract icons names and optionally {group} to group icons. For example:

config:
  sources:
    - /libraries/icon_pack/icons/{icon_id}-24.svg

Icons are located in the Drupal web root libraries folder, only with suffix -24.

config:
  sources:
    - assets/icons/{icon_id}.svg

Icons located in the Module or Theme where the EXTENSION_NAME.icons.yml file ie my_module/assets/icons/.

config:
  sources:
    - /libraries/icon_pack/icons/{group}/*.svg
    - /libraries/other_pack/icons/{group}/*.svg

The group metadata will be extracted, it's used for example in contrib module UI Icons to have a library of icons.

The `settings` key

The settings key allow to define any setting specific to the Icon Pack that will be generated as a Drupal Form when the icon is used and pass to the Twig template.

The format follow the JSON Schema reference.

For example a common usage is to include a size or width and height option to control the icon. For example:

settings:
  size:
    title: "Size"
    description: "Set a size for this icon."
    type: "integer"
    default: 32

This will allow the user to fill a size form alongside the Icon form. And the value will be passed to the template, so you can use them:

<img class="icon icon-{{ icon_id|clean_class }}" src="{{ source }}" width="{{ size|default(24) }}" height="{{ size|default(24) }}">

It is highly recommended to provide default in the Twig template as default values in the settings form are just indicative.

The `template` key

The key template provide a Twig template to render the Icon.
Available variables in the template are based on the extractor used.

To keep an accessible content, check the ARIA: presentation role documentation.

For example with svg extractor and a size setting:

my_pack:
  extractor: svg
  settings:
    size:
      title: "Size"
      type: "integer"
      default: 32
  template: >-
    <svg
      xmlns="http://www.w3.org/2000/svg"
      class="icon icon-{{ icon_id|clean_class }}"
      width="{{ size|default(32) }}"
      height="{{ size|default(32) }}"
      fill="currentColor"
      aria-hidden="true"
    >
      {{ content }}
    </svg>

The `library` key

The key library provide a way to include JavaScript and CSS assets with your icons.
This is intended for JavaScript or Class based icons.

The value must be a valid Drupal library declared in a module or theme, see Drupal assets documentation to declare one that can be included with your icon pack.

Optional metadata keys

pack_metadata:
  enabled: true # Default true if not set, if false the icons will not be discovered
  label: Wildcards # Optional label
  description: Icons from wildcard path # Optional label
  links:
    - https://www.drupal.org
  version: 1.0.0 # Optional version
  license:
    name: GPL-3.0-or-later
    url: https://www.gnu.org/licenses/gpl-3.0.html
    gpl-compatible: true

Metadata keys and values will be available for contrib modules, for example module UI Icons will use them for a library of icons.

The optional `preview` key

The key preview provide a Twig template to render the Icon in the back office context for a contrib module. This could be an Icon selector preview, the library...

This template access the same variables as the template but it must allow to display the icon in a square ratio of 48x48px to allow consistent preview.

This is optional as core extractors already include a preview template, this value is intended for custom extractor that display the icon in a different way.

For example, font based icons need this value as example for Material icons.

How to add an Extractor

An extractor is a Plugin based class to allow discovering icons to make them available in your Drupal.

Modules can add additional extractors by creating an IconExtractor plugin (PHP attribute discovery). An extractor must implement the IconExtractorInterface.

For example Iconify Icons module provide a specific Iconify extractor as iconify.
Module UI icons provide a web font extractor as font.

Render an icon with PHP

An icon can be rendered using a new icon render element

$build['icon'] = [
  '#type' => 'icon',
  '#pack_id' => 'material_symbols',
  '#icon_id' => 'home',
  '#settings' => [
    'size' => 64,
  ],
];

Properties are:

  • #pack_id: (string) Icon Pack provider plugin id
  • #icon_id: (string) Name of the icon
  • #settings: (array) Settings sent to the inline Twig template

If pack or icon id are not provided or invalid there will be no error and the element will be returned and processed with an empty icon string.

Render an icon with Twig

An icon can also be rendered using a new icon() Twig function, settings are passed as third parameter:

{{ icon('material_symbols', 'home', {size: 64}) }}

Parameters are in order:

  • The icon pack id, required string
  • The icon ID, required string
  • An array of settings for the icon, optional array|null

If pack or icon id are not provided or invalid there will be no error and no value returned.

Contrib module

Module UI Icons is leveraging this API to enable Drupal integration.

Help improve this page

Page status: Needs review

You can: