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

Nova Font Awesome Field Laravel Package

norman-huth/nova-font-awesome-field

A Laravel Nova field that adds a Font Awesome icon picker to your forms. Browse and search icons, store the selected class name, and display it in index and detail views. Easy to install and configure for any Nova resource.

View on GitHub
Deep Wiki
Context7

Getting Started

Before you install anything, note the package's status: last release April 2023, archived, 3 stars, 0 dependents. Treat it as a reference implementation you may need to vendor into your app rather than a dependency you can lean on long-term. Check the src/ directory and README first — the field is small enough to read end-to-end in one sitting, and that will be faster than guessing at its API.

  1. Install (Nova is a paid package, so the nova dependency must already resolve in your project):
    composer require norman-huth/nova-font-awesome-field
    
  2. Confirm Nova compatibility. The package predates Nova 5 (Dec 2023). If you're on Nova 4, expect it to work; on Nova 5, smoke-test before committing.
  3. Make sure Font Awesome CSS is actually loaded in the Nova frontend — the field stores a class string, it does not ship the icon font. Add FA via Nova::style() in NovaServiceProvider, or a @stack/layout override.
  4. Add the field to a Resource. Use a plain string column (e.g. icon, nullable) on the model:
    use NormanHuth\NovaFontAwesomeField\FontAwesome; // verify exact namespace in src/
    
    FontAwesome::make('Icon')
        ->help('Pick a Font Awesome icon')
        ->rules('nullable', 'string', 'max:255'),
    
  5. First use case: a nullable icon column on a taxonomy/menu/category-style model, rendered in Blade as <i class="{{ $model->icon }}"></i>.

The single most important mental model: the field produces a Font Awesome class string (e.g. fa-solid fa-house). Everything else — validation, rendering, search — is your responsibility.

Implementation Patterns

Store the raw class, render it everywhere. The value is portable: Nova index columns, Blade views, API resources, mail templates. Keep it as one string column and never store HTML.

// app/Nova/Category.php
public function fields(Request $request)
{
    return [
        Text::make('Name'),
        FontAwesome::make('Icon')
            ->nullable()
            ->default('fa-solid fa-star')
            ->hideFromIndex(),
        Text::make('Icon', fn () => $this->icon
            ? "<i class=\"{$this->icon}\"></i>"
            : '—'
        )->asHtml()->onlyOnIndex(),
    ];
}

Restrict the picker per-resource. If the field exposes icon-set narrowing (check src/ for the setter), use a small curated list per model — a menu icon set is different from a status-badge icon set. If it doesn't expose one, wrap FontAwesome::make() in a small custom field class and hardcode the set there.

Normalise on save with a mutator so bad data never reaches the DB, regardless of whether it came from Nova, a seeder, or an importer:

protected function icon(): Attribute
{
    return Attribute::set(fn ($value) => $value
        ? preg_replace('/[^a-z0-9\- ]/i', '', $value)
        : null);
}

Pair with a icon_label / icon_color field rather than overloading one column. Colour is a separate Nova Color field; combining them into one string is the classic mistake here.

Seed and import via the class string directly. You don't need the field to write data:

Category::create(['name' => 'Home', 'icon' => 'fa-solid fa-house']);

This is why the package is thin and why you can drop it later without a data migration.

Search integration. If you use Nova search or Laravel\Scout, exclude the icon column from text search — searching fa-solid returns noise. Add a small accessor (icon_name) if you want human-searchable labels.

Reuse across Nova surfaces. The same class string works in Nova's MenuSection, tool cards, NovaSettings panels, and custom cards, provided you render it in a Vue component with the FA classes available. Keep a single Blade partial resources/views/partials/icon.blade.php and include it from both Nova and app views so the markup never drifts.

Gotchas and Tips

  • Archived is the headline risk. No security patches, no Nova 5 fixes, no PHP 8.4 support. If you adopt it, pin the exact version and open a ticket in your own backlog to vendor the field (php artisan nova:field style) within a quarter. For a field this small, copying it is often cheaper than defending the dependency.
  • Font Awesome version mismatch. FA5 uses fa fa-* and fas/far; FA6 uses fa-solid fa-*. The package's picker may emit one and your frontend CSS may load the other, producing invisible icons with no error. Verify by inspecting the rendered <i> class against the CSS you actually ship.
  • Zero dependents means zero community testing. Any Nova-version breakage shows up as a Vue compile error or a blank field component, not a helpful exception. If the field renders blank, check the browser console for a failed nova-components asset load before touching PHP.
  • Asset publishing. Nova tool/field packages usually need php artisan vendor:publish --tag=... (check the README for the tag) and a npm run dev/npm run prod in the package directory if compiled assets are missing. The archived state means the shipped dist/ may be older than your Node toolchain expects.
  • Validation is entirely yours. Without ->rules(), a user (or a crafted request) can store arbitrary strings in the column, which you then echo into class="..." in Blade. Always pair the field with nullable|string|max:255 plus a mutator that strips quotes and angle brackets.
  • Don't {!! !!} the icon raw. Even with sanitisation, render as class="{{ $icon }}" inside a fixed <i> tag. Never render the stored value as unescaped HTML.
  • Index columns need explicit formatting. A Text column showing fa-solid fa-house is unreadable. Use the closure/asHtml pattern above, or hide the field from index entirely.
  • Extension points are your escape hatch. Because it's a Nova field, you can subclass it, override component(), and point at your own Vue component — this is the cleanest way to add a searchable icon grid or restrict the set without forking the whole package.
  • Debugging tip: if the picker loads but selections don't persist, confirm the column exists and is nullable in the DB and that the resource isn't using ->onlyOnForms() together with a resolveUsing that overwrites the value on save.
  • Migration path off the package: since the stored value is a plain class string, removing the package is a one-line change in fields() plus a custom Vue component or a plain Select. Keep your icon values in a config array (config/icons.php) from day one so you're never locked in.
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.
htinlynn/genius-helper
maco-studios/hephaestus
elmogy/larafast
xeviant/laravel-paystack
gorilladash/laravel-website-sdk
martialbe/flysystem-oss
chondal/3312client
jeroen-g/flickr
opscale-co/nova-genbi
itsjustvita/laravel-retention
tequilarapido/trackit
gregsphotography/site-builder-filament
cabaoctavio/laravel-query-log
gregsphotography/site-builder-components
io-digital/clickatell
snowsoft/laravel-admin
oxygen/auth
relicsoftware/barakah-payment-gateway
tobya/work-with-composer
equipc/laravel-email-validator