Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Blade Svg Laravel Package

nothingworks/blade-svg

A Laravel package for inlining SVG files directly in Blade templates. Use the @svg directive to embed icons and graphics with custom attributes and classes, plus caching for performance. Manage and style SVGs with CSS without extra HTTP requests.

View on GitHub
Deep Wiki
Context7

Getting Started

  1. Install the package:

    composer require nothingworks/blade-svg
    

    The public API is identical to the upstream blade-ui-kit/blade-icons, so upstream docs and examples apply verbatim.

  2. (Optional) Publish the config if you need custom sets or a fallback icon:

    php artisan vendor:publish --tag=blade-icons
    
  3. Create a directory for your SVGs (e.g. resources/svg/) and register it in config/blade-icons.php:

    return [
        'sets' => [
            'default' => [
                'path' => 'resources/svg',
            ],
        ],
        'fallback' => null,
    ];
    
  4. Drop an SVG file named home.svg into that folder and render it in any Blade view:

    <x-icon-home class="w-6 h-6 text-gray-500" />
    

    Or via the directive:

    @svg('home', 'w-6 h-6 text-gray-500')
    

First use case: replacing <img src="..."> icon assets in navigation, buttons, and empty states. Because the SVG is inlined, it inherits currentColor, so a single Tailwind text-* class controls the icon color and hover states work for free.

First place to look when something breaks: config/blade-icons.php (sets, paths, prefixes) and php artisan icons:cache / icons:clear. These two commands explain 90% of "my icon doesn't exist" reports.

Implementation Patterns

Multiple icon sets with prefixes. Register vendor packs alongside your own icons and give each a prefix:

'sets' => [
    'default' => ['path' => 'resources/svg'],
    'heroicons' => [
        'path' => 'vendor/blade-ui-kit/blade-heroicons/resources/svg',
        'prefix' => 'heroicon',
    ],
    'lucide' => [
        'path' => 'vendor/lucide-icons/resources',
        'prefix' => 'lucide',
    ],
],

Then <x-heroicon-o-home />, <x-lucide-search />, <x-icon-home /> all coexist. The default set renders under the icon prefix.

Dynamic icon names. The component name is resolved at parse time, so you can't interpolate inside the tag. Use the directive/helper instead:

@svg("heroicon-o-{$status}", 'w-5 h-5')
{{ svg('heroicon-o-'.$status)->class('w-5 h-5') }}

svg() returns a fluent wrapper — ->class(), ->width(24), ->height(24), or ->toHtml() — which is handy inside PHP/controllers, mailables, and Blade components with logic.

Wrapping with project defaults. Almost every app ends up with a project component that hard-codes size and accessibility:

{{-- resources/views/components/app-icon.blade.php --}}
@props(['name', 'size' => 'w-5 h-5'])
{{ svg($name)->class($size)->attributes($attributes) }}

This gives one place to enforce aria-hidden="true" for decorative icons and to switch icon packs later.

Passing arbitrary attributes. Any attribute on <x-icon-…> is forwarded to the root <svg> element, so class, id, aria-label, x-on:click, and x-bind all work naturally:

<x-icon-cog class="w-5 h-5 animate-spin" aria-hidden="true" />

Production caching. In deploy.sh, after composer install and before php artisan view:cache:

php artisan icons:cache

This writes a manifest to bootstrap/cache/blade-icons.php and turns directory scanning into a single array lookup. Run php artisan icons:clear locally whenever you add a file — otherwise you'll debug a "missing" icon that is actually just a stale manifest.

Livewire / Alpine integration. Since icons are inlined, Alpine's x-show, x-bind:class, and Livewire's DOM diffing treat them like any other element. Avoid putting an icon inside a wire:key-less loop where its id would be duplicated; if you need unique IDs (e.g. inside <defs>), generate them with Str::uuid() and pass them explicitly.

Fallback icons. Set 'fallback' => 'heroicon-o-question-mark-circle' so that a missing icon renders something in production instead of throwing — very useful for CMS-driven icon names.

Gotchas and Tips

  • The cache is the #1 source of bugs. icons:cache does not watch the filesystem. Any new SVG added after the manifest is built will 404 until you re-run it. Add icons:clear to your local dev setup or skip caching in local.
  • File-name normalization is aggressive. Icons are discovered recursively; folders become part of the name (arrows/left.svg → arrow-left in some setups), and underscores/camelCase are converted to kebab-case. Stick to lowercase-kebab filenames and you'll never have to think about it.
  • Prefix collisions. If two sets both use the default prefix (icon), the later one in the config wins silently. Always set an explicit prefix for third-party packs.
  • @svg vs <x-icon-…> resolution differ. The directive takes the full dotted/--joined name (including the set prefix), while the component uses the Blade x-{prefix}-{name} convention. Mixing them up produces "unable to locate icon" errors that look identical but aren't.
  • Class merging order. Attributes passed on the component are merged onto the <svg> root; a class you pass is appended, not replaced, so utility conflicts (w-4 vs your default w-6) follow Tailwind's stylesheet order, not the passed order. Enforce one size via a wrapper component if this bites you.
  • SVG validity matters. The package inlines the file verbatim — no sanitization. SVGs exported with hard-coded fill="#000" won't respect currentColor; strip fill and add fill="currentColor" during export or via a small pre-commit check.
  • Don't run PHP in SVGs. Unlike Blade views, the contents of an icon are not compiled. No {{ }}, no @if — template variables must be resolved before passing the icon name.
  • Case sensitivity on Linux. Home.svg works on macOS and breaks on your Linux CI/production image. Normalize filenames in review.
  • Accessibility is opt-in. The package does not add aria-hidden or role. Decorative icons should get aria-hidden="true"; meaningful ones need role="img" plus an aria-label or a <title> inside the SVG.
  • Performance. Each <x-icon-…> is an inline <svg>. A table with 200 rows × 3 icons produces 600 inline SVGs — fine for DOM size, brutal for HTML payload. For repeated icons in large lists, prefer a cached sprite sheet and <use> references.
  • Config cache ordering. If you config:cache before deploy, edits to config/blade-icons.php won't take effect until you re-run php artisan config:clear. This matters for teams that tweak prefixes per environment (e.g. different icon packs in white-label builds).
  • Extension point: implement BladeUI\Icons\Factory bindings or a custom Svg subclass if you need to post-process markup (e.g. add focusable="false"). Register it in a service provider after the package's own bindings.
  • Watch the fork. The package you install (nothingworks/blade-svg) tracks the upstream blade-ui-kit/blade-icons repository. Before adopting, confirm the fork's release cadence matches upstream — the "last release" date here (2026-06-30) is far ahead of the version most projects pin, so composer require may pull a version whose API diverges from the docs you're reading. Pin a known-good tag in composer.json and diff against upstream release notes on upgrade.
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
dbravoan/dbcms-admin-theme-dbcms
dbravoan/dbcms-theme-db-cyber
dbravoan/dbcms-blocks-basic
dbravoan/dbcms-module-content-audit
dbravoan/dbcms-module-ai-assistant
paygate-to/paygate-php
padosoft/askmydocs-connector-base
defstudio/supercharged-carbon
bernskioldmedia/laravel-matomo
bernskioldmedia/laravel-harvest
bernskiold/laravel-data-scrubber
bernskiold/laravel-currency-converter
bernskiold/laravel-campaign-monitor
bernskioldmedia/laravel-autotranslate
siberfx/telegram-bot
roy-sandip/laravel-view-extended
gregsphotography/site-builder-core
roy-sandip/laravel-view
anodyne/blade-fluentui-icons
webx-ui/module-catalog-collections