---
title: Hugo Favicon Generator
description: Hugo copies static/ to the site root and the head markup belongs to your theme. How to override the theme's head partial without editing the theme itself.
canonical: https://favicontools.com/platforms/hugo-favicon
---

# Hugo Favicon Generator

Hugo copies static/ to the root of the published site, but the head markup belongs to whichever theme you installed. The trick is overriding the theme's partial from your own project instead of editing files under themes/.

## static/ is yours, the head is the theme's

The file half is simple: everything under static/ is copied byte for byte into the published site, so static/favicon.ico is served at /favicon.ico. Files under assets/ are different — they are meant for Hugo's asset pipeline and usually come out processed and fingerprinted, which is not what a fixed icon path needs.

The markup half is where Hugo differs from everything else. The head is rendered by a template that ships with your theme, and Hugo's lookup order prefers a file in your project's layouts/ over the theme's copy at the same path. So you shadow the theme's head partial rather than modifying it.

## Where the files go

```
my-hugo-site/
  static/  # copied to the site root
    favicon.ico  <- add
    favicon-32x32.png  <- add
    apple-touch-icon.png  <- add
    site.webmanifest  <- add
  layouts/
    partials/
      head.html  <- add  # shadows the theme's copy
  themes/
    my-theme/  # leave this alone
      layouts/partials/head.html  # the file being shadowed
  hugo.toml  # or config.toml on older sites
```

## Overriding the theme's head

1. **Put the icons in static/** — No configuration needed. Hugo copies the directory's contents to the root of the published site on every build.
2. **Find the template that renders the head** — Search the theme for a head element. Most themes call a partial from their base template, but the partial's name varies — head.html and header.html are both common, and some themes split meta tags into a third file.
3. **Copy that file to the same path under your layouts/** — Same relative path, your project root instead of the theme directory. Hugo's lookup finds yours first. Copy the whole file rather than writing a stub, otherwise you drop whatever else the theme was rendering into the head.
4. **Add the link tags and rebuild** — Delete the output directory and build fresh the first time, so you know you are looking at new output rather than a leftover file.

## layouts/partials/head.html

```html
<link rel="icon" href="{{ "favicon.ico" | relURL }}" sizes="any">
<link rel="icon" type="image/png" sizes="32x32" href="{{ "favicon-32x32.png" | relURL }}">
<link rel="apple-touch-icon" href="{{ "apple-touch-icon.png" | relURL }}">
<link rel="manifest" href="{{ "site.webmanifest" | relURL }}">
```

relURL builds the path from your configured baseURL, which is what keeps the icons working when the site is published under a sub-path.

> **Never edit files under themes/:** Themes are usually installed as a git submodule or a Hugo module, so the next update reverts anything you changed there and the diff is easy to miss. The override mechanism exists precisely so you do not have to touch them.

## Hugo favicon FAQ

### static/ or assets/?

static/ for icons. Its contents are copied unchanged and keep their filenames, which is what a request for /favicon.ico needs. assets/ feeds the asset pipeline and produces processed output under generated names.

### My site lives at example.com/blog/ and the icons 404.

A hardcoded leading slash points at the domain root, not at your sub-path. Pipe the filename through relURL or absURL so the configured baseURL is applied, and check the generated HTML afterwards.

### I added the partial and nothing changed.

Then the theme is not rendering the partial you overrode. Check the base template to see which file it actually calls — if the theme calls partials/header.html and you created partials/head.html, your file is never invoked.
