Adding a Custom Favicon to the Craft CMS Control Panel

How to add custom favicons, Apple touch icons, Android icons, and all icons to the Craft CMS Control Panel.


When build­ing a Craft CMS project for a client or cus­tomer, we want to ensure they have the best author­ing expe­ri­ence pos­si­ble. Part of that expe­ri­ence is mak­ing sure the Craft CMS con­trol pan­el con­veys as much of the customer’s brand as possible. 

You might think I’m talk­ing about cre­at­ing an on-brand Craft con­trol pan­el theme. But I’m not. 

I’m talk­ing about some­thing small­er but also impor­tant: cus­tom fav­i­cons, touch icons, etc. for the Craft CMS con­trol panel.

I told you it was a small thing. 

Before we get start­ed adding our cus­tom con­trol pan­el fav­i­con, let’s make sure we first have our icons already cre­at­ed. I have my icons auto­mat­i­cal­ly cre­at­ed through my Vite build sys­tem. It takes a larg­er, high qual­i­ty source PNG image and process­es it at build time into over fifty dif­fer­ent fla­vors of icon. 

But to fol­low this tuto­r­i­al, you don’t need that many icons. You real­ly only need one: favicon.ico. A quick search on Google will help you find an icon gen­er­a­tor, or you can use one you already have for the front-end of the site.

To make the icon appear in the con­trol pan­el, we need to inject our own cus­tom code in the head ele­ment of every con­trol page. We do this through a set­ting in our config/general.php set­tings file.

You like­ly already have a lot of con­fig­u­ra­tion set­tings in this file, so let’s add it to the bot­tom. We start with the key of cpHeadTags and then open an array. 

'cpHeadTags' => [

Each tag that you want to insert is con­fig­ured as its own array, with the name of the ele­ment (e.g. link), and then its attrib­ut­es. We can insert any cus­tom ele­ment we want; it’s not lim­it­ed to icons. 

Let’s add our first gen­er­al favicon:

'cpHeadTags' => [
	['link', ['rel' => 'icon', 'href' => '/dist/assets/favicons/favicon.ico']]	

The first ele­ment in the array is the tag type (link), then the nest­ed array con­tains the attrib­ut­es for that link ele­ment. We tell it the type of link and the path or URL to the image. Dou­ble-check that you are using the cor­rect path to your fav­i­cons or icons; oth­er­wise, you’ll get a 404 error logged in your browser’s net­work tab.

Reload the con­trol pan­el (any page will do), and you should see the icon in the brows­er tab:

As well as the link ele­ment in the source code:

At this point, we can add more tags to our head ele­ment. Let’s add some addi­tion­al images, so we cov­er all of the basics. 

'cpHeadTags' => [  
    ['link', ['rel' => 'icon', 'href' => '/dist/assets/favicons/favicon.ico']],  
    ['link', ['rel' => 'icon', 'sizes' => '32x32', 'href' => '/dist/assets/favicons/favicon-32x32.png']],  
    ['link', ['rel' => 'apple-touch-icon', 'sizes' => '180x180', 'href' => '/dist/assets/favicons/apple-touch-icon-180x180.png']]  

And now we have three dif­fer­ent link ele­ments loaded in the head of every con­trol pan­el page. As I men­tioned before, this con­fig­u­ra­tion item isn’t lim­it­ed only to adding fav­i­cons. You can inject any valid ele­ment into the head of the con­trol pan­el with­out much effort.

Now our project is on-brand in big and small ways. Here’s to a good author­ing expe­ri­ence for our cus­tomers and clients!