---
title: "App Icons"
description: "Learn how metadata files work with logos."
canonical_url: "https://nuxtseo.com/docs/seo-utils/guides/app-icons"
last_updated: "2026-08-27T16:06:58.637Z"
---

## Overview

Nuxt SEO Utils automatically detects icon files in your project and generates the appropriate `link` tags in your HTML head. You **do not need to manually include these icons** - they are auto-generated based on files you place in your project.

This is based on [Next.js Metadata File](https://nextjs.org/docs/app/api-reference/file-conventions/metadata/app-icons) with an almost identical API, however runtime images are not supported.

## Setup

Simply place your icon files in either:

- The root of your `public/` directory (applies to all pages)
- Alongside your `pages/` directory (for route-specific icons)

The module will automatically detect these files and generate the appropriate HTML tags. No configuration required.

::note
Automatic means file-based: add the correctly named files, then inspect your page `<head>` or view source. You do not need to add `link` tags manually or configure icons in `nuxt.config.ts`.
::

## Generating Icons with the CLI

If you have a logo or source image, you can generate all required icon variants automatically:

```bash
npx nuxt-seo-utils icons --source logo.svg
```

This creates `favicon.ico`, `apple-touch-icon.png`, and multiple `icon-*.png` sizes. See the [CLI guide](/docs/seo-utils/guides/cli) for details.

## Naming Convention

### `favicon`

- Name: `favicon.{ico,png,svg}`

Using an `ico` file for your favicon is a good practice as all browsers support it, you can pack multiple icon sizes
into it without having to define a number of extra icon links.

The `favicon.ico` file should be placed in the `public` directory. It is supported by most browsers and displayed in the browser tab.

The module always emits an explicit link, including at the default `/` base URL.
For bitmap icons, `sizes` describes the dimensions found in the file. SVG
icons use `sizes="any"` because they scale without a fixed resolution.

**Example:** Place `favicon.ico` in `public/favicon.ico` and the module automatically generates:

```html [head output]
<link
  rel="icon"
  type="image/vnd.microsoft.icon"
  href="/base/favicon.ico"
  sizes="16x16 32x32 48x48"
/>
```

### `icon`

- Name: `*icon.{ico,jpg,jpeg,png,svg}`, `*icon-*.{ico,jpg,jpeg,png,svg}`

Icons give you greater control over the displayed icon. You can provide multiple icons and
the browser will automatically select the best icon based on the device's pixel density and use it to display the app icon.

If you have multiple icons and need to sort them, it's recommended you prefix them with their order. For example:
`1.icon.png`, `2.icon.png`, `3.icon.png`.

**Example:** Place icon files in `public/` and the module automatically generates:

```html [head output]
<link rel="icon" type="image/png" href="/1.icon.png" sizes="32x32" />
<link rel="icon" type="image/png" href="/2.icon.png" sizes="192x192" />
<link rel="icon" type="image/png" href="/3.icon.png" sizes="360x360" />
```

**Dark / light mode:** Append `-dark`, `-light`, `.dark` or `.light` to
provide both icon variants.
For example, use `favicon-dark.svg` and `favicon-light.svg`.

**Example:** Place `icon-dark.png` and `icon-light.png` in `public/` and the module automatically generates:

```html [head output]
<link rel="icon" type="image/png" href="/icon-dark.png" sizes="32x32" media="(prefers-color-scheme: dark)" />
<link rel="icon" type="image/png" href="/icon-light.png" sizes="32x32" media="(prefers-color-scheme: light)" />
```

If the app uses `@nuxtjs/color-mode`, the module updates a complete pair when
the app color mode changes.
This works when Nuxt UI installs the color mode module.
Without this module, the browser uses the `prefers-color-scheme` media query.

### `apple-touch-icon`

- Name: `*apple-icon*.{png,jpg,jpeg}`, `*apple-touch-icon*.{png,jpg,jpeg}`, `apple-touch.{png,jpg,jpeg}`

Apple touch icons are used by iOS devices to display a website's icon on the home screen and in the browser tab. You can again provide
multiple icons.

**Example:** Place `apple-icon.png` in `public/` and the module automatically generates:

```html [head output]
<link rel="apple-touch-icon" href="/apple-icon.png" sizes="180x180" />
```

## Defining Icon Tags Yourself

Static icon links in `nuxt.config.ts` take priority over inferred files of the
same role. Regular icons and Apple touch icons are resolved independently, so
defining one still allows the module to infer the other.

For a local file, the module fills missing `type` and `sizes` attributes. It
also includes `app.baseURL` in the `href` and replaces invalid bitmap sizes,
such as `sizes="any"` on an ICO file, with dimensions read from the file. A
valid subset remains unchanged. Normalizations produce a development warning.

```ts [nuxt.config.ts]
export default defineNuxtConfig({
  app: {
    head: {
      link: [
        { rel: 'icon', href: '/favicon.ico' },
      ],
    },
  },
})
```

Tags added with `useHead()` are evaluated at runtime, after build-time file
inspection. Nuxt DevTools reports missing sizes and invalid `sizes="any"`
values in the final rendered head. A runtime tag with the same `rel` and `href`
replaces the generated entry; a different `href` adds another candidate.

Set `seo.metaDataFiles` to `false` if you want runtime tags to be the only
source of icon metadata.

## Pages Directory

You can also place logos in your `pages` directory. This is useful if you want to have different logos for different pages.

The naming convention is the same as the `public` directory.

```dir
pages/
├── index.vue
├── admin/
│   ├── index.vue
│   └── icon.png
```

This will overwrite any logos in the `public` directory for all `admin` pages.

You can optionally also place your files within the `_dir` directory, which will work the same way.

```dir
pages/
├── index.vue
├── admin/
│   ├── _dir/
│   │   └── icon.png # Does the same thing!
│   └── index.vue
```