marshmallow/nova-fontawesome

A Font Awesome 6/7 Field for Laravel Nova 5

Installs: 26 711

Dependents: 1

Suggesters: 0

Security: 0

Stars: 7

Watchers: 1

Forks: 1

Open Issues: 0

pkg:composer/marshmallow/nova-fontawesome

v3.0.0 2026-01-19 15:44 UTC

README

Latest Version on Packagist Total Downloads CI

Laravel Nova Font Awesome Icons

A Laravel Nova field for selecting Font Awesome icons using the Font Awesome GraphQL API. This package loads icons on-demand via API calls, meaning you don't need to bundle all 30,000+ icons in your package.

Features

  • ๐Ÿ” Smart search - Uses Font Awesome's Algolia-powered fuzzy search
  • ๐Ÿš€ On-demand loading - Icons are fetched via API, not bundled
  • ๐Ÿ“œ Infinite scroll - Load more icons automatically as you scroll
  • ๐ŸŽจ Style filtering - Filter by solid, regular, brands, light, thin, duotone
  • ๐Ÿ‘จโ€๐Ÿ‘ฉโ€๐Ÿ‘งโ€๐Ÿ‘ฆ Family support - Classic, Brands, Duotone, Sharp, Sharp-Duotone
  • ๐Ÿ’พ Caching - API results are cached to reduce requests
  • ๐ŸŒ™ Dark mode - Full support for Nova's dark mode
  • โšก Debounced search - Prevents excessive API calls
  • ๐Ÿ“ฑ Responsive - Works great on all screen sizes
  • ๐Ÿ”„ Fallback icons - Graceful degradation when API is unavailable
  • ๐Ÿ”Ž Local fuzzy search - Instant results for common icons
  • ๐Ÿ”ง CSS Strategies - Self-hosted, Kit, or CDN CSS loading
  • ๐Ÿ”€ Legacy format support - Auto-converts FA5 classes to modern format
  • ๐Ÿ› Debug endpoint - Built-in troubleshooting tools

Important

This package was originally forked from mdixon18/fontawesome. Since we were making many opinionated changes, we decided to continue development in our own version rather than submitting pull requests that might not benefit all users of the original package. You're welcome to use this package, we're actively maintaining it. If you encounter any issues, please don't hesitate to reach out.

Requirements

  • PHP ^8.2
  • Laravel Nova ^5.0
  • Laravel 11.x or 12.x
  • Font Awesome 6.x or 7.x

Note: For Nova 4 support, use version 1.x: composer require marshmallow/nova-fontawesome:^1.0

Installation

Step 1: Install via Composer

composer require marshmallow/nova-fontawesome

Step 2: Set up Font Awesome CSS

The package needs Font Awesome CSS to render icons. Choose one of these options:

Option A: Self-hosted (Recommended for Pro users)

  1. Download Font Awesome from fontawesome.com
  2. Extract and copy the css and webfonts folders to public/vendor/fontawesome/
  3. Add to your .env:
    FONTAWESOME_CSS_STRATEGY=self-hosted
    FONTAWESOME_CSS_PATH=/vendor/fontawesome/css/all.min.css

Option B: Font Awesome Kit (Easiest for Pro)

  1. Get your Kit ID from fontawesome.com/kits
  2. Add to your .env:
    FONTAWESOME_CSS_STRATEGY=kit
    FONTAWESOME_KIT_ID=abc123def

Option C: CDN (Free icons only)

No setup needed - this is the fallback if no other strategy is configured:

FONTAWESOME_CSS_STRATEGY=cdn
FONTAWESOME_CDN_VERSION=6.5.1

Step 3: Publish config (optional)

php artisan vendor:publish --tag=nova-fontawesome-config

Step 4: Clear cache

php artisan cache:clear

That's it! The package uses the Font Awesome GraphQL API, so you don't need to manually download icon data.

CSS Loading Strategy

The package supports three CSS loading strategies (in order of priority):

1. Self-Hosted CSS (Recommended for Pro)

Download Font Awesome CSS files and host them on your server:

  1. Download Font Awesome from fontawesome.com
  2. Extract and copy to public/vendor/fontawesome/
  3. Set strategy in .env:
FONTAWESOME_CSS_STRATEGY=self-hosted
FONTAWESOME_CSS_PATH=/vendor/fontawesome/css/all.min.css

Directory structure:

public/
โ””โ”€โ”€ vendor/
    โ””โ”€โ”€ fontawesome/
        โ”œโ”€โ”€ css/
        โ”‚   โ””โ”€โ”€ all.min.css
        โ””โ”€โ”€ webfonts/
            โ””โ”€โ”€ (font files)

2. Font Awesome Kit

Use your Font Awesome Kit for automatic Pro CSS loading:

FONTAWESOME_CSS_STRATEGY=kit
FONTAWESOME_KIT_ID=abc123def

Get your Kit ID from fontawesome.com/kits

3. CDN (Fallback - Free only)

Load free icons from CDN (default fallback):

FONTAWESOME_CSS_STRATEGY=cdn
FONTAWESOME_CDN_VERSION=6.5.1

Usage

Basic Usage

use Marshmallow\NovaFontAwesome\NovaFontAwesome;

public function fields(NovaRequest $request): array
{
    return [
        ID::make()->sortable(),

        NovaFontAwesome::make('Icon'),
    ];
}

Available Methods

Set Font Awesome Version

NovaFontAwesome::make('Icon')
    ->version('6.x') // or '7.x', or specific like '6.5.1'

Limit Icon Styles

NovaFontAwesome::make('Icon')
    ->styles(['solid', 'brands']) // Only show solid and brand icons

Available styles: solid, regular, light, thin, duotone, brands

Set Icon Families

NovaFontAwesome::make('Icon')
    ->families(['classic', 'brands', 'duotone', 'sharp'])

Available families: classic, brands, duotone, sharp, sharp-duotone

Note: Duotone, Sharp, and Sharp-Duotone require Font Awesome Pro.

Free vs Pro Icons

// Only free icons (default)
NovaFontAwesome::make('Icon')
    ->freeOnly()

// Include Pro icons (requires FA Pro subscription and API token)
NovaFontAwesome::make('Icon')
    ->includePro()

Font Awesome Kit ID (Pro)

Load Pro CSS using your Font Awesome Kit:

NovaFontAwesome::make('Icon')
    ->kitId('abc123def')

Or use a custom Pro CSS URL:

NovaFontAwesome::make('Icon')
    ->proCssUrl('https://pro.fontawesome.com/releases/v6.5.0/css/all.css')

Allow Empty/Null Values

NovaFontAwesome::make('Icon')
    ->nullable()

Custom Button Text

NovaFontAwesome::make('Icon')
    ->addButtonText('Click Me!')

Limit Search Results (Per Page)

NovaFontAwesome::make('Icon')
    ->maxResults(100) // Icons per page for infinite scroll

Minimum Search Length

NovaFontAwesome::make('Icon')
    ->minSearchLength(3) // Require 3 characters before searching

Set Default Icon

NovaFontAwesome::make('Icon')
    ->defaultIcon('far', 'check-circle')

Persist Default Icon

If you want to persist the default icon (when they press clear it brings back the default so it can't be empty):

NovaFontAwesome::make('Icon')
    ->defaultIcon('far', 'check-circle')
    ->persistDefaultIcon()

Limit Available Icons

NovaFontAwesome::make('Icon')
    ->only([
        'facebook',
        'twitch',
        'twitter',
    ])

Client-Side Fuzzy Search

Enable or disable the local fuzzy search fallback:

NovaFontAwesome::make('Icon')
    ->fuzzySearch(true) // enabled by default
    ->fuzzySearchThreshold(0.3) // 0-1, lower = stricter matching

Complete Example

use Marshmallow\NovaFontAwesome\NovaFontAwesome;

public function fields(NovaRequest $request): array
{
    return [
        ID::make()->sortable(),

        Text::make('Name'),

        NovaFontAwesome::make('Icon')
            ->version('6.x')
            ->styles(['solid', 'regular', 'brands'])
            ->families(['classic', 'brands'])
            ->freeOnly()
            ->nullable()
            ->addButtonText('Choose an icon...')
            ->maxResults(100)
            ->minSearchLength(2)
            ->fuzzySearch(true)
            ->help('Select an icon to represent this item'),
    ];
}

Icon Class Format

Stored Value Format

The field stores icons in modern FA6/FA7 format:

"fa-solid fa-user"
"fa-regular fa-arrow-right"
"fa-brands fa-github"
"fa-duotone fa-solid fa-house"
"fa-sharp fa-solid fa-home"

Legacy Format Support

The package automatically supports legacy FA5 shorthand classes for backwards compatibility:

Legacy Format Converts To
fas fa-home fa-solid fa-home
far fa-user fa-regular fa-user
fab fa-github fa-brands fa-github
fal fa-star fa-light fa-star
fat fa-circle fa-thin fa-circle
fad fa-house fa-duotone fa-solid fa-house

When convert_legacy_format is enabled in config (default), legacy formats are automatically converted when saving.

How It Works

This package uses the Font Awesome GraphQL API to:

  1. Search icons - When you type in the search box, a GraphQL query is sent to Font Awesome's API
  2. Infinite scroll - Results are paginated, loading more as you scroll down
  3. Cache results - Search results are cached for 1 hour to reduce API calls
  4. Fallback gracefully - If the API is unavailable, local fallback icons are used

API Endpoints

The package registers these API routes:

  • GET /nova-vendor/nova-fontawesome/search - Search icons (with pagination)
  • GET /nova-vendor/nova-fontawesome/icon/{name} - Get a specific icon
  • GET /nova-vendor/nova-fontawesome/metadata - Get available families and styles
  • GET /nova-vendor/nova-fontawesome/config - Get CSS configuration
  • GET /nova-vendor/nova-fontawesome/convert - Convert legacy class format
  • GET /nova-vendor/nova-fontawesome/debug - Troubleshooting endpoint
  • GET /nova-vendor/nova-fontawesome/fallback - Get fallback icons

Configuration

After publishing the config file, you can modify config/nova-fontawesome.php:

return [
    // Default Font Awesome version (6.x or 7.x)
    'version' => env('FONTAWESOME_VERSION', '6.x'),

    // Cache duration in seconds (default: 1 hour)
    'cache_duration' => env('FONTAWESOME_CACHE_DURATION', 3600),

    // Only show free icons by default
    'free_only' => env('FONTAWESOME_FREE_ONLY', true),

    // Default styles to show
    'styles' => ['solid', 'regular', 'light', 'thin', 'duotone', 'brands'],

    // Available icon families
    'families' => ['classic', 'sharp', 'duotone', 'sharp-duotone', 'brands'],

    // Maximum search results per page
    'max_results' => env('FONTAWESOME_MAX_RESULTS', 100),

    // Optional API token for authenticated requests (required for Pro icons)
    'api_token' => env('FONTAWESOME_API_TOKEN'),

    // CSS loading strategy
    'css' => [
        'strategy' => env('FONTAWESOME_CSS_STRATEGY', 'self-hosted'),
        'path' => env('FONTAWESOME_CSS_PATH', '/vendor/fontawesome/css/all.min.css'),
        'kit_id' => env('FONTAWESOME_KIT_ID'),
        'cdn_version' => env('FONTAWESOME_CDN_VERSION', '6.5.1'),
    ],

    // Client-side fuzzy search settings
    'fuzzy_search' => [
        'enabled' => true,
        'threshold' => 0.3,
    ],

    // Auto-convert legacy FA5 classes to modern format
    'convert_legacy_format' => true,
];

Environment Variables

Add these to your .env file to customize the configuration:

FONTAWESOME_VERSION=6.x
FONTAWESOME_CACHE_DURATION=3600
FONTAWESOME_FREE_ONLY=true
FONTAWESOME_MAX_RESULTS=100

# CSS Strategy (self-hosted, kit, or cdn)
FONTAWESOME_CSS_STRATEGY=self-hosted
FONTAWESOME_CSS_PATH=/vendor/fontawesome/css/all.min.css

# Only needed for Pro icons
FONTAWESOME_API_TOKEN=your-api-token-here

# Pro CSS loading options (pick one)
FONTAWESOME_KIT_ID=abc123def

Getting a Font Awesome API Token

To access Font Awesome Pro icons or improve API rate limits, you'll need an API token:

  1. Create or log in to your Font Awesome account at fontawesome.com/account
  2. Navigate to API Tokens section at fontawesome.com/account#api-tokens
  3. Generate a new token by clicking "Create Token"
  4. Copy the token and add it to your .env file:
    FONTAWESOME_API_TOKEN=your-token-here

Note: API tokens are automatically exchanged for short-lived access tokens and cached for performance. The package handles token refresh automatically.

Displaying Icons

In Blade Views

<!-- Direct usage -->
<i class="{{ $model->icon }}"></i>

<!-- Or with Font Awesome Kit -->
<i class="fa-solid fa-{{ $iconName }}"></i>

With Tailwind/Vite

If rendering icons in your frontend (outside Nova), make sure Font Awesome CSS is loaded:

<!-- In your layout -->
<link rel="stylesheet" href="/vendor/fontawesome/css/all.min.css">

Or via your vite.config.js:

// Import in your JS
import '/public/vendor/fontawesome/css/all.min.css';

Helper Method (Optional)

You can add a helper to your model:

public function getIconHtmlAttribute(): string
{
    if (!$this->icon) {
        return '';
    }

    return sprintf('<i class="%s"></i>', e($this->icon));
}

Troubleshooting

Debug Endpoint

Visit /nova-vendor/nova-fontawesome/debug to check:

  • API connectivity
  • Token exchange status
  • Search functionality
  • Cache status
  • CSS configuration

Icons not loading

  1. Check the debug endpoint for API errors
  2. Check that your server can reach api.fontawesome.com
  3. Check Laravel logs for errors
  4. Clear the cache: php artisan cache:clear

CSS not loading / Icons showing as boxes

  1. Check your CSS strategy in config
  2. For self-hosted: verify files exist in public/vendor/fontawesome/
  3. For Kit: verify your Kit ID is correct
  4. Check browser console for 404 errors

Styles not filtering correctly

Make sure you're using valid style names: solid, regular, light, thin, duotone, brands

Pro icons not showing

  1. Verify you have an active Font Awesome Pro subscription
  2. Check that your API token is correctly set in .env
  3. Use the debug endpoint to verify token exchange
  4. Ensure your CSS strategy supports Pro icons (self-hosted or kit)

Upgrading

From v1.x to v2.x

  1. Update composer.json requirements
  2. Update package.json - Vite replaces Laravel Mix
  3. Rebuild assets: npm install && npm run build
  4. Update config file if published (new css section replaces pro_css)
  5. See UPGRADE.md for detailed migration guide

Development

Building Assets

npm install
npm run dev      # Development build
npm run build    # Production build
npm run watch    # Watch mode

Running Tests

composer test

Code Style

composer lint        # Fix code style
composer lint-check  # Check without fixing

Static Analysis

composer analyse

Licence

The MIT License (MIT). Please see License File for more information.

Sponsorships

If you are reliant on this package in your production applications, consider sponsoring us! It is the best way to help us keep doing what we love to do: making great open source software.

Contributing

Feel free to suggest changes, ask for new features or fix bugs yourself. We're sure there are still a lot of improvements that could be made, and we would be very happy to merge useful pull requests.

Special thanks to

Made with love for open source

At Marshmallow we use a lot of open source software as part of our daily work. So when we have an opportunity to give something back, we're super excited!

We hope you will enjoy this small contribution from us and would love to hear from you if you find it useful in your projects. Follow us on Twitter for more updates!