Favicons in Hugo

Favicons are necessary to giving your site perspective in the tab bar as well as in other interfaces. But they can be annoying to work with as you need to make and update multiple sizes. I am pretty lazy and would like to automate this.

First we'll define the sizes we want for the main favicons. 16, 32, 48 are the most common. Set in your site config file.

config.yaml

params: 
  faviconSizes: [16, 32, 48]

Next add your favicon at 310x310 minimum to assets/img/favicon.png. This will allow us to use it as a resource and process it in Hugo.

This code iterates over the sizes and creates a favicon for each from “img/favicon.png”. There are 2 references in the following code.

{{ range $i := .Site.Params.faviconSizes }} 
{{ $favicon := resources.Get "img/favicon.png" }} 
{{ $image := $favicon.Resize (printf "%dx%d CatmullRom" $i $i) }}
<link
	rel="icon"
	type="image/png"
	sizes="{{$i}}x{{$i}}"
	href="{{ $image.Permalink }}"
/>
{{ end }} 
{{ with resources.Get "img/favicon.png" }} 
	{{ $image := .Resize "180x CatmullRom" }}
	<link rel="apple-touch-icon" sizes="180x180" href="{{ $image.Permalink }}" />
{{ end }}
<link
	rel="icon"
	type="image/png"
	sizes="16x16"
	href="https://davelage.com/img/favicon_hudc4e1fae7e08ba4f142cf3cc07774103_7291_16x16_resize_catmullrom_2.png"
/>

<link
	rel="icon"
	type="image/png"
	sizes="32x32"
	href="https://davelage.com/img/favicon_hudc4e1fae7e08ba4f142cf3cc07774103_7291_32x32_resize_catmullrom_2.png"
/>

<link
	rel="icon"
	type="image/png"
	sizes="48x48"
	href="https://davelage.com/img/favicon_hudc4e1fae7e08ba4f142cf3cc07774103_7291_48x48_resize_catmullrom_2.png"
/>

<link rel="apple-touch-icon" sizes="180x180" href="https://davelage.com/img/favicon_hudc4e1fae7e08ba4f142cf3cc07774103_7291_180x0_resize_catmullrom_2.png" />

browserconfig.xml

<meta name="msapplication-config" content="/browserconfig.xml" />

So if you want to be extra lazy, we can create tile icons for browserconfig. But to be lazy you have to add a XML output format…

config.yaml

outputFormats:
  XML:
    isPlainText: false
    mediaType: application/xml
    isHtml: false
    noUgly: true
    permalinkable: false
    name: xml

layouts/_default/baseof.xml

{{ printf "<?xml version=\"1.0\" encoding=\"utf-8\" standalone=\"yes\"?>" | safeHTML }}
{{ block "main" . }}{{ end }}

layouts/_default/single.xml

{{ define "main" }}
	<browserconfig>
		<msapplication>
			<tile>
				{{ with resources.Get "img/favicon.png" }} 
					{{ $square70 := .Resize "70x70 CatmullRom" }} 
					{{ $square150 := .Resize "150x150 CatmullRom" }} 
					{{ $wide310 := .Fill "310x150 CatmullRom" }} 
					{{ $square310 := .Resize "310x310 CatmullRom" }}
					<square70x70logo src="{{ $square70.Permalink }}" />
					<square150x150logo src="{{ $square150.Permalink }}" />
					<wide310x150logo src="{{ $wide310.Permalink }}" />
					<square310x310logo src="{{ $square310.Permalink }}" />
				{{ end }}
				<TileColor>#000000</TileColor>
			</tile>
		</msapplication>
	</browserconfig>
{{ end }}

content/browserconfig.md

---
draft: false
outputs:
- xml
url: browserconfig.xml
---

Output /browserconfig.xml

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<browserconfig>
	<msapplication>
		<tile>
			<square70x70logo src="https://davelage.com/img/favicon_hudc4e1fae7e08ba4f142cf3cc07774103_7291_70x70_resize_catmullrom_2.png" />
			<square150x150logo src="https://davelage.com/img/favicon_hudc4e1fae7e08ba4f142cf3cc07774103_7291_150x150_resize_catmullrom_2.png" />
			<wide310x150logo src="https://davelage.com/img/favicon_hudc4e1fae7e08ba4f142cf3cc07774103_7291_310x150_fill_catmullrom_smart1_2.png" />
			<square310x310logo src="https://davelage.com/img/favicon_hudc4e1fae7e08ba4f142cf3cc07774103_7291_310x310_resize_catmullrom_2.png" />
			<TileColor>#000000</TileColor>
		</tile>
	</msapplication>
</browserconfig>

This is how I added favicon support to this site. I update assets/img/favicon.png and it will update the icon throughout all the different types. I set them to use CatmullRom to allow for good sharpness support.