Installation
composer require becklyn/icon-loader
Add to config/app.php under providers:
Becklyn\IconLoader\IconLoaderServiceProvider::class,
Publish Config
php artisan vendor:publish --provider="Becklyn\IconLoader\IconLoaderServiceProvider"
Edit config/icon-loader.php to define your icon directories:
'directories' => [
base_path('resources/icons'),
base_path('vendor/laravel/framework/src/Illustration'),
],
First Use Case In a Blade template:
{{ icon('folder', 'home') }} <!-- 'folder' = directory, 'home' = filename (without extension) -->
Or in PHP:
echo IconLoader::get('folder', 'home');
config/icon-loader.php (configuration)resources/views/vendor/icon-loader.blade.php (default template, if customized)app/Providers/AppServiceProvider.php (if extending functionality)Register Icons
Define directories in config/icon-loader.php:
'directories' => [
base_path('resources/icons/admin'),
base_path('resources/icons/public'),
],
Use in Blade
<!-- Single icon -->
{{ icon('admin', 'dashboard') }}
<!-- With custom class -->
{{ icon('admin', 'dashboard', ['class' => 'text-blue-500']) }}
<!-- With fallback -->
{{ icon('admin', 'dashboard', ['fallback' => '⚙️']) }}
Use in PHP
// Get raw SVG string
$svg = IconLoader::get('admin', 'dashboard');
// Get as HTML with attributes
$html = IconLoader::html('admin', 'dashboard', ['width' => '24']);
Dynamic Directories Override directories per request:
IconLoader::setDirectories(['custom_path']);
Custom Templates Publish the view:
php artisan vendor:publish --tag=icon-loader.views
Modify resources/views/vendor/icon-loader.blade.php to add wrappers or modifiers.
Caching The package auto-caches icons. Clear with:
php artisan cache:clear
Integration with Tailwind/Alpine Combine with Alpine.js for interactive icons:
<div x-data="{ open: false }">
{{ icon('admin', 'menu', ['@click' => 'open = !open']) }}
</div>
Laravel Mix/Webpack Process SVGs during build (if using inline SVGs):
// webpack.mix.js
mix.setPublicPath('public')
.js('resources/js/app.js', 'public/js')
.postCss('resources/css/app.css', 'public/css', []);
Case Sensitivity
Icon filenames are case-sensitive. Ensure consistency in Blade/PHP calls (e.g., icon('admin', 'Home') vs. icon('admin', 'home')).
Missing Directories If icons fail to load, verify:
config/icon-loader.php..svg extension (no trailing slashes in filenames).Caching Issues After adding new icons, clear the cache:
php artisan cache:clear
php artisan view:clear
SVG Validation Malformed SVGs may break rendering. Validate with:
composer require --dev squizlabs/php_codesniffer
phpcs --standard=PSR12 path/to/svg
Namespace Conflicts
Avoid naming conflicts with Laravel’s default icons (e.g., home.svg in resources/icons vs. Laravel’s built-in home illustration).
Check Loaded Icons Dump the registry:
dd(IconLoader::getRegistry());
Log Missing Icons Add a fallback with logging:
@php
$icon = IconLoader::get('admin', 'missing-icon');
if (empty($icon)) {
\Log::warning('Icon "admin/missing-icon" not found');
}
@endphp
{{ $icon ?? '❌' }}
Inspect SVG Output Use browser dev tools to verify SVG content. Check for:
<!-- Valid SVG -->
<svg>...</svg>
<!-- Broken (missing closing tag) -->
<svg>
Custom Icon Resolvers
Extend the resolver logic in app/Providers/AppServiceProvider.php:
public function boot()
{
IconLoader::extend(function ($directory, $name) {
// Custom logic (e.g., fetch from API)
return file_get_contents("https://api.example.com/icons/{$name}.svg");
});
}
Add Icon Metadata
Store metadata (e.g., title, description) in a JSON file alongside SVGs:
// resources/icons/admin/metadata.json
{
"dashboard": {
"title": "Dashboard",
"tags": ["home"]
}
}
Load via:
$metadata = json_decode(file_get_contents(base_path("resources/icons/admin/metadata.json")), true);
Dynamic Icon Directories Use a trait to dynamically set directories per controller:
use Becklyn\IconLoader\Traits\DynamicIconDirectories;
class AdminController {
use DynamicIconDirectories;
public function __construct()
{
$this->setIconDirectories(['admin']);
}
}
Icon Size Utilities
Add helper methods to app/Helpers/icon.php:
if (!function_exists('iconSmall')) {
function iconSmall($directory, $name, $attributes = [])
{
return IconLoader::html($directory, $name, array_merge(['width' => '16', 'height' => '16'], $attributes));
}
}
Usage:
{{ iconSmall('admin', 'settings') }}
Default Template Override
If modifying resources/views/vendor/icon-loader.blade.php, ensure the template includes:
@if (isset($attributes['class']))
<svg {{ $attributes }}>{{ $svg }}</svg>
@else
<svg class="icon" {{ $attributes }}>{{ $svg }}</svg>
@endif
Icon Loader Instance Access the singleton instance via:
$loader = app('icon-loader');
$svg = $loader->get('admin', 'home');
Testing Icons Mock the loader in tests:
$this->app->instance('icon-loader', Mockery::mock(IconLoader::class));
How can I help you explore Laravel packages today?