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 Fontisto Icons Laravel Package

codeat3/blade-fontisto-icons

Blade Fontisto Icons provides simple Blade components for the Fontisto icon set, letting you drop scalable SVG icons into any Laravel view with a single tag. Install via Composer, then render icons by name with optional size and styling—no asset pipelines or extra configuration needed.

View on GitHub
Deep Wiki
Context7

Getting Started

Install (30 seconds).

composer require codeat3/blade-fontisto-icons

No service-provider registration, no php artisan vendor:publish, no config file, no asset build step. Laravel auto-discovery registers the provider and the package exposes its SVG set as Blade components. Confirm the resolved graph before you commit:

composer show codeat3/blade-fontisto-icons        # version, requires
composer show blade-ui-kit/blade-icons            # the transitive dependency that matters
composer why codeat3/blade-fontisto-icons

First use case — drop an icon into a view. The documented form is a single component with a name prop:

<x-fontisto-icon name="home" class="w-4 h-4 text-gray-500" />

Depending on the registered prefix in the installed version, the per-icon form <x-fontisto-home /> may also (or instead) be what's available. Verify once, at the top of your first spike, then never think about it again:

ls vendor/codeat3/blade-fontisto-icons/resources/svg | head -30   # the actual vocabulary & exact names
sed -n '1,120p' vendor/codeat3/blade-fontisto-icons/src/*ServiceProvider.php

Render one icon in a scratch route and view-source it. If you see <svg …> in the HTML, you are done — do not proceed to build anything else until you've seen inline SVG.

Where to look first, in order:

  1. vendor/codeat3/blade-fontisto-icons/resources/svg/ — this directory is the documentation. Icon names are the filenames minus .svg. Treat it as the source of truth, not the upstream marketing site.
  2. The service provider — tells you the exact component name/prefix and whether it uses blade-ui-kit/blade-icons.
  3. composer.json of the package — the illuminate/* and php constraints. The 1.6.0 notes say "Laravel 13 compatible" but say nothing about the floor; if you are on Laravel 11/12, this line is what tells you whether you were dropped.

Do this before the first real page: create your own wrapper and make it the only thing feature views are allowed to use.

resources/views/components/icon.blade.php

The first use case that pays for the whole package is a nav or dashboard: home, search, user, settings, bell, chevron-down. Roughly ten glyphs cover most chrome, and Fontisto has all of them.

Implementation Patterns

1. Wrap the vendor component on day one. The single highest-value thing you will write is a five-line adapter. It gives you accessibility defaults the vendor component doesn't inject, one place to pin sizing, and a one-file swap if you ever change icon sets.

{{-- resources/views/components/icon.blade.php --}}
@props(['name', 'title' => null])

@if ($title)
    <x-fontisto-icon
        :name="$name"
        role="img"
        aria-label="{{ $title }}"
        {{ $attributes->merge(['class' => 'inline-block shrink-0']) }}
    />
@else
    <x-fontisto-icon
        :name="$name"
        aria-hidden="true"
        focusable="false"
        {{ $attributes->merge(['class' => 'inline-block shrink-0']) }}
    />
@endif

Then ban <x-fontisto-icon> outside that file via a review checklist or a grep in CI:

! grep -rl 'x-fontisto-' resources/views --exclude=components/icon.blade.php

2. Sizing and colour are CSS, not props. The package renders inline SVG, so the icon inherits currentColor and is sized by the box you give it. Prefer a class over an inline width/height, and never pass numbers as attributes:

<x-icon name="search" class="size-5 text-slate-500 hover:text-slate-900" />

If an icon refuses to scale, the SVG file itself carries hardcoded width/height attributes. Beat them with CSS (svg { width: 1em; height: 1em } on your wrapper class) rather than editing vendor files.

3. Icon + label vs icon-only button. Icons inside a labelled button or link are decorative — aria-hidden is correct, and the visible text is the accessible name. Icon-only controls need the label moved onto the control, not the icon:

<button type="button" class="p-2 rounded hover:bg-slate-100">
    <x-icon name="trash" class="size-4" />
    <span class="sr-only">Delete invoice</span>
</button>

4. Dynamic icon names — whitelist, always. A status badge is the most common reason you'll want a variable name. Never interpolate user data:

@php
    // closed set, defined in PHP — not from the request
    $statusIcon = match ($order->status) {
        'paid'     => 'check',
        'pending'  => 'clock',
        'failed'   => 'close',
        'shipped'  => 'truck',
        default    => 'question',
    };
@endphp

<x-icon :name="$statusIcon" class="size-4" />

If you must go fully dynamic, use @switch/match or an enum map to a literal, and keep the name prop server-controlled. <x-dynamic-component :component="'fontisto-icon'"/> driven by request input is an injection surface and a guaranteed InvalidArgumentException at 2am.

5. Build an internal icon gallery — this is the real enablement artifact. The vocabulary is ~600 glyphs and discovery is the actual support burden, not defects. One route, one view, no dependencies:

Route::get('/dev/icons', function () {
    $files = glob(base_path('vendor/codeat3/blade-fontisto-icons/resources/svg/*.svg'));

    return view('dev.icons', [
        'icons' => collect($files)->map(fn ($f) => basename($f, '.svg'))->sort()->values(),
    ]);
})->middleware('can:viewDevTools');
<div class="grid grid-cols-6 gap-3">
    @foreach ($icons as $icon)
        <div class="flex flex-col items-center gap-1 p-2 border rounded">
            <x-icon :name="$icon" class="size-6" />
            <code class="text-[10px] break-all">{{ $icon }}</code>
        </div>
    @endforeach
</div>

Gate it behind a dev-only middleware or app()->isLocal(). Every "does this set have a printer icon?" question now has a URL answer.

6. Migrating off a webfont or CDN set. Keep the wrapper's prop surface identical to the old class convention so the swap is mechanical. Fontisto's own CSS classes are fi fi-*; map them once:

{{-- before --}} <i class="fi fi-home"></i>
{{-- after  --}} <x-icon name="home" class="size-4" />

Sweep file by file, not with a blind regex — fi-check → check is safe, but compound names (arrow-right, angle-down, file-1) will silently become arrowright and render nothing.

7. Testing. Icons are server-rendered, so assertSee works, and you can assert on the component name in tests that care about markup:

$response->assertSee('aria-hidden="true"', false);
$this->get('/dashboard')->assertOk();  // smoke-test: a bad icon name blows up render

A cheap regression guard: a test that loops your app's icon constants and asserts each SVG file exists. It catches vendor-set changes on composer update before production does.

8. Versioning policy. Pin the minor ("^1.6"), let the lockfile govern, and treat the package as a leaf presentation dependency — never let an icon component type leak into domain code, jobs, or mailables' logic (mailables are fine; use the component, keep no icon logic there).

Gotchas and Tips

  • Icon names are the filenames, and they're hyphenated. arrow-right, angle-down, checkbox-active, sometimes numeric suffixes (file-1). Guess-and-check wastes hours; ls the svg directory once and keep the gallery from pattern 5 deployed on dev.
  • An unknown icon name does not always fail loudly. Depending on blade-icons' fallback configuration it can render an empty SVG — a blank space that looks like a layout bug. Add the icon-literal regression test in pattern 7 and you'll never chase one.
  • currentColor means fill won't work as you expect. Colour comes from color, not fill. If a Tailwind text-* class appears ignored, check whether a parent is setting fill directly.
  • Attributes land on the root <svg>, not a wrapper. Your class merges into the SVG's own class list — useful, but it means margins and flex behaviour apply to the SVG box. Wrap in a <span> only when you genuinely need a positioned container.
  • The SVGs ship with baked-in width/height. Many icon distributions do. Override in CSS rather than editing vendor files (which composer update will silently revert).
  • No accessibility attributes are injected. This is expected, not a bug — the vendor component is a raw SVG renderer. Your <x-icon> wrapper is where aria-hidden / role="img" / <title> belong. Audit your wrapper once, and every icon in the app inherits the fix.
  • Inline SVG duplicates markup on icon-dense pages. Twenty icons in a table means twenty copies of the path data, uncompressed and uncached per row. If you're rendering hundreds, measure the HTML payload before wide rollout; beyond that threshold a local sprite or a per-icon partial cache is the right move. For a dashboard, this will never matter.
  • After install, if nothing renders: you're probably looking at compiled views. php artisan view:clear, then re-check. Also confirm you're in a Blade view — this package does nothing for Inertia/Vue/Livewire templates unless you're writing Blade syntax inside them.
  • Laravel 13 is supported; that's the whole of 1.6.0. No new icons, no API change. If you're on 11/12, upgrading 1.5.0 → 1.6.0 buys you nothing functionally — but do check the package's composer.json for a raised floor before treating it as a no-op.
  • Transitive dependency is the real compatibility surface. This package's tag being Laravel 13-ready means nothing if the resolved blade-ui-kit/blade-icons and its illuminate/* constraints aren't. In a scratch branch, actually run the resolution against your target framework version.
  • Component-name collisions. If another package in a multi-package app registers a fontisto- prefix (or you're using multiple codeat3/blade-*-icons packages), verify the registry. Low likelihood, but the symptom — one icon set winning over the other — is confusing to debug from a view.
  • License and attribution. Fontisto's bundled icon license (icon sets are usually SIL OFL or CC-BY) likely carries attribution obligations distinct from this package's own MIT license. Add both to third-party notices; the MIT on the wrapper is not the whole story.
  • Pin it and review it quarterly. One maintainer, one star, zero dependents. None of that is disqualifying for a generated, leaf, presentation-only package whose failure mode is "an icon is blank" — but it does mean composer audit and a periodic composer outdated on this line are worth a calendar reminder. The escape hatch is already built if you followed pattern 1: swapping icon sets is a change to icon.blade.php plus a name-mapping table, not a template rewrite.
  • Don't fork it to fix one icon. It's static SVG plus a service provider; if you need one glyph the set lacks, drop your own <x-app-icon> component beside it rather than inheriting maintenance of ~600 files.
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.
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums
rlacerda83/query-parser
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings