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

Laravel Favicon Laravel Package

beyondcode/laravel-favicon

Generate a complete set of favicons for your Laravel app from a single source image. The package provides an Artisan command and Blade helpers to create and reference favicon files, simplifying setup and keeping your markup clean.

View on GitHub
Deep Wiki
Context7

Getting Started

Install and publish the config.

composer require beyondcode/laravel-favicon
php artisan vendor:publish --provider="BeyondCode\LaravelFavicon\FaviconServiceProvider"

Open config/favicon.php first — this is where the whole package lives. Read it top to bottom: source image path, output directory, sizes/formats, Apple touch icon, manifest settings, and cache behaviour. Do not accept the defaults blindly; the output path is the one setting that interacts with your deploy artifact and Vite.

Drop in one source asset. Commit a single high-resolution, square, transparent PNG (1024×1024 is a safe default) to a versioned location outside the generated output directory. Do not use SVG — the image library will fail at generation time, not at config time.

Generate once, by hand, to verify.

php artisan favicon:generate

Then wire the Blade directive into your base layout <head>:

@include('favicon::links')

or the component/directive form documented by the package — check the published config and repo README for the exact directive name in your version, since it has shifted historically.

First real use case: environment-visible favicons. Render a different source image (or a badge overlay) for staging vs production so a tab is instantly identifiable. That is the package's stated premise and the fastest way to confirm the full pipeline — config → generation → markup — works end to end.

Verify before moving on:

  • php -m | grep -E 'gd|imagick' inside every environment (local, CI, production image).
  • The output directory exists and is writable.
  • curl -I the generated icon URLs and confirm a 200.
  • View source in the browser and confirm exactly one <link rel="icon">, not a duplicate from your framework default or Vite.

Implementation Patterns

Build-time generation, never on-request. This is the single decision that makes everything else simple. Add generation to your deploy pipeline:

php artisan favicon:generate

Run it as a step after assets are built and before the app is marked healthy. This keeps image decoding and disk writes off the request path, makes multi-instance deploys deterministic (every instance gets identical output), and works on read-only container filesystems — the write happens in a build layer, not at runtime. If generated icons must be served by your app, ship them inside the deploy artifact so every instance has them.

Config-driven environment branding. Point the source at an env-specific asset and let config resolve it:

// config/favicon.php
'source' => env('FAVICON_SOURCE', resource_path('brand/favicon.png')),

Then set FAVICON_SOURCE per environment. This turns rebrands and staging/production differentiation into a one-line config change rather than a design hand-off. For multi-tenant or white-label variants, run generation per tenant in a build step with the source path parameterised — but be aware this is stretching the package past its design intent; if tenants multiply, move to a dedicated asset pipeline.

Wire the directive exactly once. Put the Blade directive in your base layout only. If you have multiple layouts (app, auth, error pages), have them all extend the same base so the icons are declared in one place. Then diff the rendered <head> for duplicates if you also use a framework default or Vite plugin that emits icon tags.

Cache-aware regeneration. The package caches generated icons for fast repeat requests. When the source image changes, the cache is your enemy — a stale favicon is the most common post-rebrand bug. Make regeneration part of the same pipeline step that handles the source change, and treat the cache directory as a build artifact (clear it in the build, not in production).

Vite coexistence (the deliberate decision). Favicons use stable, unhashed public paths, which sit outside Vite's manifest model. That is fine, but record it: do not try to route favicons through @vite, and do not let a Vite plugin also emit icon tags. Choose one owner for the <link rel="icon"> element and enforce it in review.

Pin the version you start on. Begin at 1.9.0 — the only release claiming Laravel 13 support. Use a caret constraint (^1.9) unless you are compliance-sensitive, in which case pin exactly.

Gotchas and Tips

GD/Imagick missing is a late failure. Containers routinely ship without the image extension. composer require succeeds; the first generation blows up. Add a CI assertion:

php -r "var_dump(extension_loaded('gd') || extension_loaded('imagick'));"

and fail the build on false. This belongs in the runbook, not in someone's memory.

Read-only filesystems break the write silently. Serverless, immutable images, and read-only containers won't surface the failure until first render. Moving generation to build time is the fix; the fallback is mounting a writable path for output only.

Watch intervention/image v2→v3, not Laravel. The most likely future cliff is the underlying image library’s major version, not the framework's. When you plan upgrades, check the package's permitted range for the image library and whether it accepts v3. This is the upgrade that will actually bite.

Large source images can exhaust memory. A multi-megabyte 4000px source decoding under a low memory_limit fails in generation, not configuration. Downscale the source to a sane 1024×1024 before committing, and keep memory_limit generous in the generation step of the pipeline.

Stale favicons outlive your deploy. Browsers and CDNs cache favicons aggressively — often more than your deploy cadence. After a rebrand, expect to explain why someone still sees the old tab icon. Versioning the output path or query-stringing the icon URLs is the reliable escape hatch if it becomes a support burden.

Duplicate <link rel="icon"> is the classic integration bug. Framework defaults, Vite plugins, and the package's directive can all emit icon tags. Grep the rendered head in CI or review. Two competing declarations produce confusing, browser-specific behaviour.

SVG sources fail at generation. The package expects a raster source for raster outputs. Convert first, commit the PNG.

Don't extend it into PWA territory. Apple touch icon and web app manifest support are in scope; splash screens, maskable icons, and a full PWA icon set are not. If the roadmap needs those, that is a separate solution — forcing this package into that role creates a false expectation with stakeholders.

Treat it as maintenance-mode, not roadmap. Recent activity is automated compatibility PRs. Support depth is the weak dimension; the mitigation is that fork-and-patch, or a hand-rolled Artisan command, is roughly a day of work. Keep it off the critical path, and re-review at each Laravel major and each image-library major.

Verify the 1.8.0→1.9.0 diff before adopting. Confirm it is constraint-and-CI only, with no behavioural change hiding in a "compatibility" release. That check gates the rest of the evaluation and takes minutes.

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.
pharaonic/laravel-notification-dependencies
beautinow/translug
dev-brainiac/bot-cloaked
octoberrain/html
octoberrain/extension
octoberrain/exception
octoberrain/contracts
frankyso/ipaymu
3mdikram/worldmoneywords
snowsoft/config
itmosoft/laravel-subscriptions
larva/laravel-ai-qwen
adachsoft/api-version-bundle
cgv/localized-resource
noith/settings
kda/laravel-package
kda/filament-dynamic-navigation
bypersoft/signbox
pairus/product-data
fayne/laravel-filament-cms-core