CollectFrontendIconsEvent 

\FGTCLB\AcademicBase\Event\CollectFrontendIconsEvent lets code contribute icons to the frontend icon registry of this extension. It is meant for icons whose identifiers are only known at runtime, read from a configuration file of an extension for example. An icon a package ships with a fixed identifier belongs in its Configuration/FrontendIcons.php instead.

category_types uses the event for the icons of the category types and category groups an installation registers.

When it is dispatched 

The registry dispatches the event each time it is built, before it reads the Configuration/FrontendIcons.php files of the active packages. The registry is kept with the system caches, so that happens when the cache entry is missing, after the system caches were flushed, and when vendor/bin/typo3 cache:warmup builds it. It does not happen per request: whichever request or command finds the cache entry missing builds it for the whole installation. What a listener contributes therefore changes only after the system caches are flushed again.

What a listener reads and changes 

Method What it does
addIcon(string $identifier, string $providerClass, array $options = []) Contributes the icon $identifier , rendered by the icon provider $providerClass with $options , the options of an entry of Configuration/FrontendIcons.php without provider , source for example. A second call for the same identifier replaces the first one.
getIcons() The icons contributed so far, in the format of Configuration/FrontendIcons.php.

Example: icons from code 

An extension that computes its icons, from a configuration file of its own for example, contributes them through the event. It is dispatched while the registry is built, before the files are read, so an entry of a Configuration/FrontendIcons.php with the same identifier replaces a contributed icon whatever the order of the two packages.

EXT:my_extension/Classes/EventListener/ContributeFrontendIcons.php
<?php

declare(strict_types=1);

namespace MyVendor\MyExtension\EventListener;

use FGTCLB\AcademicBase\Event\CollectFrontendIconsEvent;
use TYPO3\CMS\Core\Attribute\AsEventListener;
use TYPO3\CMS\Core\Imaging\IconProvider\SvgIconProvider;

#[AsEventListener(identifier: 'my-extension/contribute-frontend-icons')]
final readonly class ContributeFrontendIcons
{
    public function __invoke(CollectFrontendIconsEvent $event): void
    {
        $event->addIcon(
            'my-extension-badge',
            SvgIconProvider::class,
            ['source' => 'EXT:my_extension/Resources/Public/Icons/badge.svg'],
        );
    }
}
Copied!

addIcon() rejects a provider that is not an icon provider with an error that names the icon.

Rules and pitfalls 

  • A file always wins. The contributed icons come first and the files are merged over them, so a site package replaces a contributed icon by registering the same identifier in its Configuration/FrontendIcons.php, whatever the loading order of the packages.
  • Flush after a change. A changed listener, or a change to what it reads, reaches the frontend after vendor/bin/typo3 cache:flush --group system , see Caching.
  • One registry for every site. Do not make what a listener contributes depend on the request, the site or the language. The registry is built once for the whole installation, by a command as often as by a request.
  • Only real providers. addIcon() throws an \InvalidArgumentException with code 1791061902 for a class that does not implement \TYPO3\CMS\Core\Imaging\IconProviderInterface . An icon registered for the frontend only is unknown to the icon registry of TYPO3, so an icon the backend shows as well is registered there, too.

Introduced in