diff --git a/README.md b/README.md index 83e13d9..6e82dba 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,7 @@ Fetch, convert, and cache favicons for any website in your Laravel app. -Given a site URL, the package discovers the best available icon source (preferring an SVG over an ICO over a raster PNG/WebP/AVIF over a JPG), downloads it, and converts it into whichever size/format you ask for — caching the result on disk so subsequent requests are instant until the TTL expires. +Given a site URL, the package discovers the best available icon source (preferring an SVG over the largest PNG/WebP/AVIF over an ICO over a JPG), downloads it, and converts it into whichever size/format you ask for — caching the result on disk so subsequent requests are instant until the TTL expires. ## Requirements diff --git a/config/favicon.php b/config/favicon.php index 9fc3225..c3f0993 100644 --- a/config/favicon.php +++ b/config/favicon.php @@ -71,14 +71,17 @@ | | Lower number = preferred. Used to rank candidate favicon sources found | on the page ( tags, manifest icons, /favicon.ico fallback). + | Format outranks declared size, so 'ico' sits below the modern rasters: + | a favicon.ico rarely holds more than 64px and would otherwise beat a + | site's 512px PNG, leaving every larger variant upscaled. | */ 'source_priority' => [ 'svg' => 0, - 'ico' => 1, - 'png' => 2, - 'webp' => 2, - 'avif' => 2, + 'png' => 1, + 'webp' => 1, + 'avif' => 1, + 'ico' => 2, 'jpg' => 3, 'jpeg' => 3, 'gif' => 4, diff --git a/tests/Feature/FaviconResolutionTest.php b/tests/Feature/FaviconResolutionTest.php index 36d6229..f13997e 100644 --- a/tests/Feature/FaviconResolutionTest.php +++ b/tests/Feature/FaviconResolutionTest.php @@ -36,6 +36,25 @@ function sampleSvg(): string expect($info[0])->toBe(32)->and($info[1])->toBe(32); }); +it('prefers the largest declared png over a declared favicon.ico', function () { + $ico = (new \Backstage\Favicon\ImagickConverter(config('favicon'))) + ->toIco(samplePng(), 'png', [16, 32]); + + Http::fake([ + 'https://icoandpng.test/' => Http::response( + '' + ), + 'https://icoandpng.test/favicon.ico' => Http::response($ico), + 'https://icoandpng.test/icon-512.png' => Http::response(samplePng(512)), + ]); + + Favicon::for('https://icoandpng.test')->get('png', 32); + + $meta = Favicon::readMeta(Favicon::domainKey('https://icoandpng.test')); + + expect($meta['source_url'])->toBe('https://icoandpng.test/icon-512.png'); +}); + it('falls back to /favicon.ico when no link tags are present', function () { $ico = (new \Backstage\Favicon\ImagickConverter(config('favicon'))) ->toIco(samplePng(), 'png', [16, 32]);