Search by

justinholtweb / craft-fav

justinholtweb

Favicons for Craft CMS — upload one square image in the control panel and Fav generates every icon a browser, a phone and a pinned tile ask for, then puts the right tags in every page.

Package info

github.com/justinholtweb/craft-fav

Type:craft-plugin

pkg:composer/justinholtweb/craft-fav

Statistics

Installs: 0

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

dev-main 2026-08-29 12:50 UTC

This package is auto-updated.

Last update: 2026-08-29 12:53:20 UTC


README

Fav

Fav

Favicons for Craft CMS 5 — one image in, every icon a browser asks for out.

Upload one square image in the control panel. Fav generates the .ico, the PNGs, the iOS home screen icon, the Windows tile, the web manifest and the tile config, then puts the tags for them in the head of every page. No template changes, no build step, no dependencies, no third-party favicon generator to paste twelve files back from.

It is free, in one edition, with everything switched on.

Requirements

Craft CMS 5.3+ and PHP 8.2+.

Installation

From the Plugin Store, or:

composer require justinholtweb/craft-fav
php craft plugin/install fav

What comes out of one image

File What wants it
favicon.ico 16, 32 and 48px in one file — browser tabs, bookmarks, crawlers, link unfurlers
favicon-16x16.pngfavicon-96x96.png Modern browsers, which prefer a PNG when offered one
icon.svg Copied through when the source is an SVG, for tab strips on high-density screens
apple-touch-icon.png The iOS home screen, at 180px, flattened onto your background colour
icon-192.png, icon-512.png Android launchers and install prompts, through the manifest
mstile-150x150.png Windows pinned tiles
manifest.json The two icons above and your two colours
browserconfig.xml The tile, and its colour

Set the theme colour, the background colour, the tile colour and an optional padding, and Fav does the rest. Each site in a multi-site install has its own set.

Where the tags go

By default Fav splices them into every front-end HTML page, just before </head>. Nothing to add to a template.

A page whose template already declares an icon of its own is left alone, so a hand-built head keeps working. Turn that off in the settings if you would rather Fav's tags were added anyway — they go in last, which is the copy the browser keeps.

To place them yourself:

{{ craft.fav.tags() }}

Calling that stands the automatic injection down for the page it runs on, so nothing appears twice. Also available:

{{ craft.fav.tagList() }}                     {# the tags as a list, to place individually #}
{{ craft.fav.url('apple-touch-icon.png') }}   {# a URL, for an Open Graph image or an email #}
{{ craft.fav.favicon().themeColor }}          {# the set itself, for its colours #}

/favicon.ico

Browsers, crawlers and link unfurlers ask the site root for /favicon.ico by name whether or not a page links to one. Fav answers it. Craft only sees the request when there is no real file at that path, so a favicon somebody put in the web root still wins.

The control panel

Fav also replaces the control panel's own favicon with the primary site's, so a browser window full of control panels tells you which client you are looking at. Off by default.

Where the files live

Generated files go in web/fav/<site uid>/ and are served by the web server as ordinary static files. If the web root is not writable — a read-only deploy, a containerised production box — they go to storage/fav/ instead and are served through Craft, and everything else works the same.

Because they live outside the database, a fresh deployment has the settings but not the files:

php craft fav/favicons/generate            # every site, only what is out of date
php craft fav/favicons/generate default    # one site
php craft fav/favicons/generate --force    # rebuild regardless
php craft fav/favicons/status              # what each site has, and whether it is current
php craft fav/favicons/clear               # delete the generated files, keep the settings

Replacing the source image in the assets index regenerates the set on the spot, so the tab does not keep showing last year's logo.

Source images

A square PNG, 512×512 or larger, with transparency if the artwork has any. A non-square image is contained rather than cropped — a wide logo is never sliced to make it fit.

An SVG works too, and is copied through as a vector icon as well as being rasterised, but only on servers running Imagick. GD cannot rasterise vector artwork, and its failure is a blank PNG rather than an error, so Fav refuses it and says so on the screen.

Settings

Setting Default What it does
autoInject true Add the tags to front-end pages automatically
skipPagesWithIcons true Leave pages that already declare an icon alone
serveRootIcon true Answer /favicon.ico
applyToCp false Use the primary site's favicon in the control panel
regenerateOnAssetSave true Rebuild when the source image changes
cacheDuration 604800 Seconds a browser may cache an icon served through PHP

All of them can be set in config/fav.php.

Already running a PWA plugin?

Turn Fav's web manifest off for that site. Two <link rel="manifest"> tags in one head is one too many, and the PWA's is the one that has to win — it carries the start URL and display mode that make the site installable. Fav's manifest deliberately carries neither.

Permissions

One: Manage favicons. Anyone without it does not see the section.

Licence

MIT.