Skip to content

Authoring & Distribution

When to Use

Shipping a custom icon pack inside a theme or module.

Decision: ship in a theme vs a module

Scope Where
Icons specific to one theme/site Inside the theme
Icons reusable across sites/themes Inside a custom module
Public distribution Custom contrib module on drupal.org

Pattern

1. Place icon assets at the theme/module root:

my_theme/
  icons/
    arrow-left.svg
    arrow-right.svg
    menu.svg
    close.svg

2. Declare the pack in my_theme.icons.yml at the theme root:

my_theme_icons:
  label: "My Theme Icons"
  extractor: svg
  config:
    sources:
      - icons/*.svg
  settings:
    size:
      title: "Size"
      type: integer
      default: 24
    decorative:
      title: "Decorative"
      type: boolean
      default: false
  template: >
    <svg xmlns="http://www.w3.org/2000/svg"
         width="{{ size|default(24) }}" height="{{ size|default(24) }}"
         viewBox="0 0 24 24"
         {% if decorative %}aria-hidden="true"{% endif %}>
      {{ content|raw }}
    </svg>

3. (Optional) Attach a CSS library for supporting styles (font-face for font extractor, base classes for path extractor):

# my_theme.libraries.yml
icon-styles:
  css:
    theme:
      css/icons.css: {}

4. Clear cache (drush cr). Visit the Library admin page to confirm the pack is discovered.

Common Mistakes

  • Wrong: editing icon files but not seeing changes → Right: clear plugin.manager.icon_pack cache
  • Wrong: using the same pack_id as an already-installed contrib pack → Right: always prefix with the theme/module name; ID collisions are unpredictable
  • Wrong: forgetting to whitelist <svg> and <symbol> in text formats when icons go through filtered text → Right: update the allowed HTML list in affected text formats

See Also