robwdwd/svg-icon-bundle
robwdwd/svg-icon-bundle is a Symfony bundle for organizing and rendering SVG icons in Twig templates. It offers icon set management, caching, and simple helpers for embedding scalable, styleable SVG icons without external image requests, making icon usage consistent and fast.
composer require robwdwd/svg-icon-bundle
Symfony path (the supported one): enable the bundle in config/bundles.php (Robwdwd\SvgIconBundle\SvgIconBundle::class => ['all' => true]), point the bundle's config at a directory of .svg files, then render an icon in Twig. The only public surface is almost certainly a single Twig function — open the bundle's Twig extension class first to confirm its name and signature (svg_icon('name') is the conventional shape), and open the DI extension to see the config key for the icon path. That's a five-minute read and it tells you everything the README might not.
Laravel path: there is no Flex auto-discovery and no Laravel service provider here, so composer require alone gives you nothing. Either (a) instantiate the bundle's renderer directly in a small SvgIconServiceProvider of your own and expose it as a Blade directive, or (b) — usually the right call — read the ~50 lines that do the file lookup and reimplement them. First use case in both worlds is the same: replace <img src="/icons/logo.svg"> with inline <svg> markup so the icon inherits fill: currentColor, participates in CSS animations, and costs zero extra HTTP requests.
One canonical icon directory, kebab-case names. Keep every icon in resources/icons/ with a flat namespace and reference it without the extension. Resist nested folders until you actually need them — path handling is where most of these packages get sloppy.
Blade directive, not a compile-time include. Register @svg('logo') as a directive that compiles to {!! app(SvgIconRenderer::class)->render('logo') !!}. Do the file read at render time, not at Blade compile time, or new icons won't appear until view:clear.
Always emit unescaped. {{ }} will HTML-entity the markup and print <svg> on the page. This is the #1 first-hour bug.
Treat the icon as a component, not a string. Wrap the renderer in a tiny helper that accepts attributes — svg('logo', ['class' => 'w-5 h-5', 'aria-hidden' => 'true']) — so callers control sizing and semantics. Stripping the SVG's hardcoded width/height and injecting a viewBox on the way out is what makes icons responsive.
Cache the file contents, keyed on mtime. Cache::rememberForever("icon:{$name}:".filemtime($path), fn () => file_get_contents($path)) gives you edit-fresh icons with no per-request disk I/O. In a monorepo where you share icons with a Symfony app, you get the same behavior on both sides.
Don't loop inline SVGs for large sets. If a page renders the same icon 20 times, or you have 100+ icons, an SVG sprite (<symbol> + <use>) is dramatically lighter. This package doesn't do sprites; know that ceiling before you commit to it.
App\Support\SvgIcon class and you eliminate a supply-chain risk for the price of an afternoon.<script>, onload=, and <foreignObject> inside an SVG do execute when inlined. Only ever inline icons you authored or vetted; if any SVG can come from a user upload, run it through a sanitizer (enshrined/svg-sanitize) first.svg_icon('../../.env') is a file-read primitive. Allowlist against scandir() of the icon directory and assert realpath($path) is prefixed by the icon root.<?xml ...?> and sometimes <!DOCTYPE svg ...>, which are invalid mid-document. Regex them off during render.id="gradient" or id="clip0" will fight; the second one silently renders wrong. Namespace IDs on render, or forbid IDs in your icon style guide.viewBox don't scale. Fixed width/height attributes win over CSS in some browsers; strip them and require a viewBox at lint time.aria-hidden="true"; informative ones need role="img" plus a <title> or aria-label.symfony/* / twig/* ranges can create dependency conflicts if you're also running Symfony components anywhere in the tree. Run composer why-not before you're surprised by it in CI.How can I help you explore Laravel packages today?