Weave Code
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

Filament Favicon Laravel Package

pxlrbt/filament-favicon

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require pxlrbt/filament-favicon
    

    Publish the config (if needed) with:

    php artisan vendor:publish --provider="pxlrbt\FilamentFavicon\FilamentFaviconServiceProvider"
    
  2. First Use Case: Add a FaviconColumn to a Filament table to display favicons for domains stored in a model:

    use pxlrbt\FilamentFavicon\Filament\FaviconColumn;
    
    public function table(Table $table): Table
    {
        return $table
            ->columns([
                FaviconColumn::make('domain')
                    ->label('Website Favicon'),
                // ... other columns
            ]);
    }
    
  3. Where to Look First:

    • README for basic usage.
    • config/filament-favicon.php for caching and request settings.
    • src/Filament/FaviconColumn.php and src/Filament/FaviconEntry.php for customization hooks.

Implementation Patterns

Core Workflows

  1. Domain Extraction: Use state() to transform URLs into domains:

    FaviconColumn::make('url')
        ->state(fn ($record) => parse_url($record->url, PHP_URL_HOST))
        ->label('Favicon');
    
  2. Caching Strategy: Leverage the built-in caching (default: filament-favicon-cache) to avoid repeated HTTP requests:

    // Override cache driver in config/filament-favicon.php
    'cache' => [
        'driver' => 'redis',
        'key' => 'filament-favicon-cache',
    ],
    
  3. Integration with Filament Resources: Combine with FaviconEntry in infolists for a cohesive UI:

    public function table(Table $table): Table
    {
        return $table->columns([
            FaviconColumn::make('domain'),
        ]);
    }
    
    public function getTableInfolistItems(): array
    {
        return [
            FaviconEntry::make('domain'),
            // ... other entries
        ];
    }
    
  4. Dynamic State Handling: Use closures for dynamic domain resolution (e.g., from user-provided data):

    FaviconColumn::make('website')
        ->state(fn ($record) => $record->getDomainFromComplexData())
        ->extraAttributes(['class' => 'w-8 h-8']);
    

Advanced Patterns

  1. Custom Fetch Logic: Extend the FaviconFetcher service to handle non-standard domains (e.g., IP addresses):

    // app/Providers/FilamentFaviconServiceProvider.php
    public function register()
    {
        $this->app->bind(\pxlrbt\FilamentFavicon\Contracts\FaviconFetcher::class, function () {
            return new class implements \pxlrbt\FilamentFavicon\Contracts\FaviconFetcher {
                public function fetch(string $domain): ?string
                {
                    // Custom logic for IP-based domains
                    return $domain === '127.0.0.1' ? 'data:image/svg+xml;base64,...' : null;
                }
            };
        });
    }
    
  2. Conditional Rendering: Hide the column/entry based on record state:

    FaviconColumn::make('domain')
        ->visible(fn ($record) => filled($record->domain))
        ->hiddenLabel();
    
  3. Asset Optimization: Pre-fetch favicons during model hydration (e.g., via app/Models/Concerns/FetchesFavicon.php):

    public function getFaviconAttribute()
    {
        return cache()->remember(
            "favicon-{$this->domain}",
            now()->addHours(1),
            fn () => FaviconFetcher::fetch($this->domain)
        );
    }
    

Gotchas and Tips

Pitfalls

  1. Domain Validation:

    • The package assumes valid domains (e.g., example.com). Invalid inputs (e.g., user@example.com) may break fetching.
    • Fix: Sanitize domains with filter_var($domain, FILTER_VALIDATE_DOMAIN).
  2. Caching Quirks:

    • Cache keys are prefixed with filament-favicon-. Clear the cache if favicons appear stale:
      php artisan cache:clear
      
    • Tip: Use php artisan filament-favicon:clear-cache (if the package adds this command).
  3. HTTPS/HTTP Mixed Content:

    • Favicons fetched over HTTP may trigger browser warnings. Ensure your app uses HTTPS or configure the fetcher to enforce HTTPS:
      // In config/filament-favicon.php
      'fetch_options' => [
          'ssl' => [
              'verify_peer' => false, // Disable for self-signed certs (not recommended for production)
              'verify_peer_name' => false,
          ],
      ],
      
  4. Rate Limiting:

    • Aggressive scraping (e.g., fetching favicons for 1000+ domains) may trigger 429 errors.
    • Tip: Implement exponential backoff in a custom fetcher or use a queue:
      use Illuminate\Support\Facades\Queue;
      
      Queue::later(now()->addSeconds(2), fn () => FaviconFetcher::fetch($domain));
      

Debugging

  1. Log Fetch Failures: Enable debug logging in config/filament-favicon.php:

    'debug' => env('FILAMENT_FAVICON_DEBUG', false),
    

    Check logs for failed requests (e.g., storage/logs/laravel.log).

  2. Manual Testing: Test favicon fetching manually via the FaviconFetcher facade:

    use pxlrbt\FilamentFavicon\Facades\FaviconFetcher;
    
    FaviconFetcher::fetch('google.com'); // Returns base64 string or null
    
  3. Common HTTP Errors:

    • 404: Domain has no favicon. Handle gracefully:
      FaviconColumn::make('domain')
          ->default('data:image/svg+xml;base64,...') // Fallback icon
          ->extraAttributes(['onerror' => 'this.src="fallback-icon.png"']);
      

Extension Points

  1. Custom Favicon Sources: Override the default favicon URL pattern (e.g., to support custom paths):

    // In a service provider
    $this->app->bind(\pxlrbt\FilamentFavicon\Contracts\FaviconUrlResolver::class, function () {
        return new class implements \pxlrbt\FilamentFavicon\Contracts\FaviconUrlResolver {
            public function resolve(string $domain): string
            {
                return "https://custom-cdn.com/favicons/{$domain}.ico";
            }
        };
    });
    
  2. React Components: Extend the Blade component for custom UI (e.g., add tooltips):

    // resources/views/vendor/filament-favicon/components/favicon.blade.php
    <img
        src="{{ $src }}"
        alt="{{ $label }}"
        class="{{ $classes }}"
        onerror="this.src='{{ asset('images/fallback.png') }}'"
        title="{{ $domain }}"
    >
    
  3. Testing: Mock the FaviconFetcher in tests:

    $this->app->instance(\pxlrbt\FilamentFavicon\Contracts\FaviconFetcher::class, MockFetcher::new());
    

Performance Tips

  1. Batch Fetching: For large datasets, fetch favicons in batches using Laravel queues:

    // Dispatch a job for each domain
    FaviconFetchJob::dispatch($record->domain);
    
  2. Lazy Loading: Defer favicon fetching until the column is rendered:

    FaviconColumn::make('domain')
        ->lazyLoad()
        ->extraAttributes(['loading' => 'lazy']);
    
  3. CDN Caching: Serve favicons via a CDN with long cache headers (e.g., Cache-Control: public, max-age=31536000).

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.
milito/query-filter
apiboxsym/user-bundle
apiboxsym/health-check-bundle
jayeshmepani/jpl-moshier-ephemeris-php
elnasnato/laraliveui
labrodev/rest-sdk
sampaui/sampaui
babelqueue/php-sdk
facebook/capi-param-builder-php
babelqueue/symfony
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours