abetwothree / laravel-iconify-api
A package to create a local API for the dynamic Iconify Icon components
Package info
github.com/abetwothree/laravel-iconify-api
pkg:composer/abetwothree/laravel-iconify-api
Fund package maintenance!
Requires
- php: ^8.4
- ext-json: *
- illuminate/contracts: ^13||^12||^11.0
- pcrov/jsonreader: ^1.0
- spatie/laravel-package-tools: ^1.16
Requires (Dev)
- larastan/larastan: ^3.1
- laravel/pint: ^1.21
- nunomaduro/collision: ^8.1.1||^7.10.0
- orchestra/testbench: ^11.0||^10.0.0||^9.0.0
- pestphp/pest: ^4.1.6||^3.0.0
- pestphp/pest-plugin-arch: ^4.0.0||^3.0.0
- pestphp/pest-plugin-laravel: ^4.0.0||^3.0.0
- phpstan/extension-installer: ^1.4
- phpstan/phpstan-deprecation-rules: ^2.0
- phpstan/phpstan-phpunit: ^2.0
This package is auto-updated.
Last update: 2026-08-03 01:28:26 UTC
README
Make your Laravel Application an API for on demand icons using the Iconify icon web components.
This Laravel package creates a few API routes for the Iconify icons on demand API. It allows you to easily use on demand icons and use your Laravel applicatioin as the Iconify API.
It works similarly to the Node Iconify API and is a spiritual successor to their PHP implementation.
On demand icons work great whether you use Livewire, Inertia, or just plain Blade views to render your Laravel application and want to render icons dynamically using a single component.
Additionally, this package provides a convenient way to render Iconify icons inline as SVGs within PHP files or in your Blade views.
Also By Me
Requirements
- PHP 8.5, 8.4
- Laravel 13.x, 12.x or 11.x
How To Use
Install the package via composer:
composer require abetwothree/laravel-iconify-api
In your core application blade layout file add the following directive in the head section before your application's JS bundle:
@iconify
This will configure the Iconify API on demand icons to load the icons from your Laravel application instead of the Iconify API.
By default Icon API routes will work out of the following route path in your Laravel application:
/iconify/api
The following routes are currently available:
/iconify/api/{prefix}.json?icons={icon-prefix}- Returns icon SVG data for an icon set. Icon prefix can be comma separated for multiple icons./iconify/api/{prefix}/icons.json?icons={icon-prefix}- Same as above./iconify/api/collections- Returns a list of icon collections available in your application./iconify/api/collection?prefix={prefix}- Returns the information for a specific icon collection.
How To Display Dynamic On-Demand Icons
To display on-demand icons follow the instructions on the Iconify on demand docs and use any of their component libraries in your Laravel Application.
You also need icon set data to be available in your application. You'll need to install the icon set data using NPM. See more info here.
It is recommended to install individual icon sets instead of the entire Iconify JSON set to keep your application lightweight. However, you can install the entire set if you wish and this package will work with either approach.
Real-Time Inline Icon Rendering
In addition to the HTTP API, this package can render icons directly to SVG in PHP for places where you want immediate server-side output.
The icon finding and caching goes through the same process as the HTTP API, ensuring consistent behavior and performance.
Helper function
Use the global helper to render an icon string:
$svg = icon('heroicons:clock');
Apply SVG attributes:
$svg = icon('heroicons:clock', [ 'class' => 'w-6 h-6', 'data-slot' => 'icon', ]);
Blade component
Use the Blade component for direct rendering in views:
<x-icon name="heroicons:clock" /> <x-icon name="heroicons:clock" class="w-6 h-6" /> <x-icon name="heroicons:clock" data-slot="icon" />
Supported options
Both the helper and the Blade component accept the same options as the official Iconify components. Anything not listed here is passed through as a plain SVG attribute, except
viewBox, which is always computed from the icon data, and option keys that are not well-formed XML attribute names, which are skipped.
That last rule checks the attribute name only — a key like 'x onload=alert(1)' would otherwise open a second, live attribute, since escaping does not touch it. Well-formed keys such as onclick still render, exactly as they would through a Blade attribute bag.
Values are rendered when they are a string, a number, a boolean, or an object with a __toString(). Anything else — an array, a closure, a plain object — is skipped rather than emitted as an empty attribute.
| Option | Values | Effect |
|---|---|---|
width, height |
number, CSS length, auto, unset |
Icon size. Defaults to 1em. One side is derived from the other by aspect ratio. unset, undefined and none omit both attributes entirely. A falsy value (0, '', false) falls back to 1em; the string '0' is kept, matching JavaScript truthiness. |
color |
any CSS color | Applied via style="color: …", matching React's style.color = value. Only affects monotone icons (those using fill="currentColor" / stroke="currentColor"). As an inline style it beats any non-!important CSS rule — it was previously a color="…" attribute, which such a rule could override. A value containing ;, {, }, /* or */ could inject a second declaration and is dropped entirely; rgb(1,2,3), hsl(210 100% 50%), var(--x, red), currentColor and color-mix(...) are unaffected. |
inline |
true |
Adds vertical-align: -0.125em so the icon sits on the text baseline. |
rotate |
1–3, "90deg", "25%" |
Quarter-turn rotation. Non-quarter values are ignored. |
flip |
"horizontal", "vertical", "horizontal,vertical" |
Flip shorthand. |
hFlip, vFlip |
true |
Flip on one axis. |
h-flip, horizontal-flip, horizontalFlip |
true |
Aliases for hFlip. |
v-flip, vertical-flip, verticalFlip |
true |
Aliases for vFlip. |
aria-hidden |
anything other than true |
Removes the default aria-hidden="true". |
<x-icon name="heroicons:clock" width="32" color="rebeccapurple" inline /> <x-icon name="heroicons:clock" rotate="90deg" h-flip="true" />
$svg = icon('heroicons:clock', ['width' => 32, 'color' => 'rebeccapurple', 'inline' => true]);
A style you supply yourself is always emitted last, so it overrides the color and
inline styles the package generates.
The framework-only props Iconify's React/Vue/Svelte components accept — icon, mode,
ssr, onLoad, children, fallback, customise, _ref — are accepted and ignored
rather than emitted as attributes. Alternate render modes (mode="bg", mode="mask")
are not implemented; icons always render as inline <svg>.
Naming and collision safety
If your app already has a global helper or component with the same name, this package will skip registration and leave existing behavior untouched.
You can also customize or disable each one in config/iconify-api.php:
'inline' => [ 'enabled' => true, 'defaults' => [ 'class' => '', // Any default SVG attribute or render option is supported. // Examples: // 'data-source' => 'iconify-api', // 'style' => 'vertical-align: middle;', // 'width' => '1.5em', // 'inline' => true, ], 'helper' => [ 'enabled' => true, 'name' => 'icon', ], 'component' => [ 'enabled' => true, 'name' => 'icon', ], ],
Values from defaults are applied to every rendered icon. Per-icon options (helper or Blade attributes) override matching keys, except class, which is merged. Render options such as width, height, rotate, flip, inline and color are honoured here too, not just plain SVG attributes.
PHPStan support
This package ships a PHPStan stub for the default helper name icon, so static analysis can recognize icon() calls out of the box.
If you rename the helper function (for example to iconify_svg), add a small project-level stub so PHPStan can recognize the custom function name:
<?php if (! function_exists('iconify_svg')) { /** * @param array<string, mixed> $options */ function iconify_svg(string $name, array $options = []): string {} }
Then include that stub in your phpstan.neon:
parameters: stubFiles: - stubs/icon-helper.stub.php
Advanced Configuration
To configure the package, you can publish the config file using the following command:
php artisan vendor:publish --tag="iconify-api-config"
This will publish a iconify-api.php file in your config directory. You can then configure the package to your liking.
For advanced setting details, please see the config file.
If you update your configuration file, make sure to break your application cache with the following commands:
php artisan config:clear php artisan cache:clear php artisan view:clear
Icon Caching
This package uses Laravel's caching system to cache the icon data to make repeated requests for the same icon faster. It caches icon data when it is requested so that it only caches the icons that are actually used in your application.
You can set which cache store to use for this package in your config/iconify-api.php file. Otherwise, it will use your default cache store setting.
A found icon is cached without an expiry — it cannot change while the installed version of the icon set stays the same. Nothing keys off the icon set file, so upgrading an icon package invalidates nothing: run php artisan cache:clear after npm update @iconify/json or after upgrading an @iconify-json/* package, or a redrawn icon keeps serving its old body indefinitely, on both the API routes and icon('set:name').
A "this icon does not exist" result is cached only briefly, because any name a caller invents produces one; not_found_cache_ttl controls how long (300 seconds by default, 0 to skip caching misses entirely). The API routes also bound how many names one request may ask for, via max_icons_per_request (200 by default, 0 for no limit); a request above the limit is rejected with a 400.
Cache keys are {cache_key_prefix}:{icon-set-prefix}:icon:{shape-version}:{icon-name} for icons and {cache_key_prefix}:{icon-set-prefix}:meta:… for icon set metadata. Icon names are not filtered, so a name a cache key cannot hold — one carrying a space, a :, a /, a control character or any other byte outside printable ASCII (so a non-ASCII name always hashes), or longer than 128 bytes — is replaced in that last segment by h: and a SHA-256 of the whole name; no icon set published through @iconify/json contains such a name, but a hand-authored one reached through a custom icons_location may, and its keys will not be readable back to a name. The shape version changes when the cached array shape does, which orphans the older entries rather than migrating them — run php artisan cache:clear after upgrading this package too, if you want the space back straight away.
Missing Features
The MVP of this package was to provide an API for on demand icons in your Laravel Application. A few API endpoints that currently exist on the Node JS package that are missing in this package and will be added in future releases:
- Return icon data in in JSONP callback format.
- List icons in a collection.
- List icons categorized in a collection.
- Search endpoint for icons.
- Keywords endpoint for icons.
Changelog
Please see CHANGELOG for more information on what has changed recently.
Contributing
Please see CONTRIBUTING for details.
Security Vulnerabilities
Please review our security policy on how to report security vulnerabilities.
Code Quality
This package uses the following code quality tools:
- PHPStan 2.x at level 10 for static analysis.
- Laravel Pint for consistent code style.
- PHP Pest for testing.
Credits
License
The MIT License (MIT). Please see License File for more information.