You need a unified, performant system for managing icons across Drupal 11.1+ rather than hand-rolling SVG, icon fonts, or external resources in templates and CSS; Icon API's PHP classes are marked experimental/internal, so treat *.icons.yml and icon() as the stable surface.
You need to understand how icon packs are discovered, loaded, and rendered; schema validation only runs when justinrainbow/json-schema is installed, and the render element carries no #cache of its own.
You're creating a new icon pack and need the full YAML structure; only extractor and template are schema-required, and settings: default: values never reach the Twig template — repeat them with |default().
Select the right extractor by icon source and remoteness; svg_sprite cannot read a remote sprite (discovers zero icons, silently), and local sources are restricted to svg/png/gif.
You have local SVG files and want automatic discovery and template-controlled inline rendering; the extractor does not sanitize — it only refuses remote sources, so treat every file in the pack as trusted code.
You have a large local SVG sprite and want one cached request for every icon; remote sprites cannot work — IconFinder refuses any URI with a scheme, so a CDN sprite source discovers nothing.
You need to reference icon files by URL — local svg/png/gif or any remote format; path never reads the file server-side, and {icon_id} is not expanded in remote URLs, so one URL means one icon.
You have an icon font with codepoint metadata and want it in Icon API via the UI Icons contrib module; .woff2 sources are silently skipped, and {{ content }} exists only for .codepoints sources — guard it with |default(icon_id).
Add icon fields, menu icons, or CKEditor integration
You need icon fields, menu icons, or CKEditor embedding beyond core rendering; link-field icons ship from ui_icons_field (no separate Link submodule), and ui_icons_ckeditor5 needs ui_icons_text to actually render the embed.
You're writing icon pack templates and need the real variable set; caller settings override extractor data but icon_id/source always win, and the pack definition's own keys (label, provider, ...) leak into context too.
icon(pack_id, icon_id, settings) is the only signature; icon('pack:id') is a fatal ArgumentCountError/TypeError on every Drupal 11 release, never a deprecation — a missing icon just returns [] with no error.
You're building SDC components that need configurable icon props; YAML default: is never applied and required: runs behind assert(), off in production — write the Twig so it's correct with no props declared at all.
Your component needs maximum icon flexibility via slots; under {% embed %} a slot value arrives as a Twig block, so {% if icon %}{{ icon }}{% endif %} is silently false — render every slot as {% block name %}{% endblock %}.
You need programmatic icon access in PHP; getIcons() returns discovery arrays with no label (call getIcon()->getLabel() for that), and the render element properties are #pack_id/#icon_id — #pack/#icon renders nothing, raises nothing.
Icon pack definitions cache in cache.discovery under cid icon_pack (icon_pack_plugin is a tag, not the cid); nothing watches *.icons.yml file changes, and the icon render element itself adds no #cache — add your own on the parent.
Pick the extractor by repetition, not icon count: svg is 0 HTTP requests since it inlines server-side, so 'switch to sprites to cut requests' is backwards — sprites only win when one icon repeats many times on a page.
Core does not sanitize SVG anywhere; the svg extractor inlines file contents unescaped and only refuses remote sources, so review every file you ship as trusted code — never route user uploads through Icon API.
path records a URL and the visitor's browser fetches it; svg filters remote sources out; svg_sprite accepts a remote source and then reads zero icons. SSRF applies only to a custom extractor you write that calls httpClient().
Icons aren't appearing or pack IDs aren't resolving; without justinrainbow/json-schema, validateDefinition() returns TRUE unconditionally and a bad pack fails later at render time with IconPackConfigErrorException instead.
Migrating to Icon API from manual markup, an icon font, or image files; search-and-replacing old markup into icon('pack:id') is fatal — the Twig function always takes pack and icon as two separate arguments.
Core/contrib extractors don't cover your source; discoverIcons() must key by the full pack_id:icon_id or the icon lists but never renders, and overriding loadIcon() with a different signature is fatal at class load.