AI Favicon
Tutorial2026-03-17· 8 min read

How to Add Favicons to Your Next.js App (App Router)

A step-by-step walkthrough for setting up favicons in Next.js 14+ with the App Router. Covers file conventions, metadata API, and common pitfalls.

Next.js 13 introduced the App Router, which changed how favicons work. Instead of manually writing link tags in a custom document, you drop files into the app/ directory and Next.js generates the metadata automatically. It is simpler once you understand the conventions, but the documentation leaves gaps that trip people up.

The File Convention Approach

The easiest method is to place specially named files in your app/ directory. Next.js recognizes these filenames and generates the appropriate <link> and <meta> tags in your HTML head automatically.

File structure
app/
  favicon.ico          → <link rel="icon" />
  icon.png             → <link rel="icon" type="image/png" />
  icon.svg             → <link rel="icon" type="image/svg+xml" />
  apple-icon.png       → <link rel="apple-touch-icon" />
  opengraph-image.png  → <meta property="og:image" />
  twitter-image.png    → <meta name="twitter:image" />

That is it for the basics

If you place these files in your app/ directory and run your dev server, Next.js handles all the metadata. No configuration file needed, no import statements, nothing in your layout component. The framework does it automatically based on filenames.

Size Requirements

Next.js is flexible about input sizes, but browsers have specific expectations. Getting the sizes wrong will not break anything, but it will produce blurry icons on some devices.

FileRecommended SizeWhy
favicon.ico48x48 (multi-size)Covers 16, 32, 48px needs
icon.png512x512Sharp on high-DPI displays
apple-icon.png180x180Apple requirement for home screen
opengraph-image.png1200x630Aspect ratio for social cards
twitter-image.png1200x675Twitter card aspect ratio

The Manifest Approach

For Progressive Web Apps and Android devices, you also need a web manifest that lists your icons. Next.js supports this through an app/manifest.ts file.

app/manifest.ts
import type { MetadataRoute } from 'next'

export default function manifest(): MetadataRoute.Manifest {
  return {
    name: 'My App',
    short_name: 'App',
    start_url: '/',
    display: 'standalone',
    background_color: '#ffffff',
    theme_color: '#DA7756',
    icons: [
      {
        src: '/icon-192.png',
        sizes: '192x192',
        type: 'image/png',
      },
      {
        src: '/icon-512.png',
        sizes: '512x512',
        type: 'image/png',
      },
      {
        src: '/icon-maskable-512.png',
        sizes: '512x512',
        type: 'image/png',
        purpose: 'maskable',
      },
    ],
  }
}

The Metadata API Approach

If you need more control, say, different icons per route or dynamic icons, you can use the generateMetadata function instead.

app/layout.tsx
import type { Metadata } from 'next'

export const metadata: Metadata = {
  icons: {
    icon: [
      { url: '/favicon.ico', sizes: '48x48' },
      { url: '/icon.svg', type: 'image/svg+xml' },
    ],
    apple: '/apple-icon.png',
  },
}

Do not mix approaches

If you use both the file convention (dropping files in app/) and the metadata API to define icons, Next.js uses the metadata API and ignores the files. Pick one approach and stick with it.

Common Pitfalls

Favicon not updating in development

Browsers cache favicons aggressively. If you replace your favicon and the old one still shows up, open a new incognito window or do a hard refresh (Ctrl+Shift+R). The dev server sometimes needs a restart too.

Favicon shows on localhost but not in production

Check that your files are in the app/ directory, not public/. In the App Router, the file convention specifically looks in app/. Files in public/ are served statically but do not trigger automatic metadata generation.

However, if your manifest.ts references icon paths like /icon-192.png, those files should be in public/ since the manifest URLs are served as-is.

Apple Touch Icon is the wrong size

Apple expects exactly 180x180 pixels for the apple-icon.png. If you provide a different size, iOS will resize it, and the result often looks blurry. Generate your icons at the correct dimensions from the start.

The Complete Setup

Here is the full set of files for a Next.js App Router project that covers all browsers, mobile, PWA, and social sharing.

Complete file list
app/
  favicon.ico              # Multi-size ICO (16, 32, 48)
  icon.png                 # 512x512 PNG
  icon.svg                 # SVG with dark mode support
  apple-icon.png           # 180x180 Apple Touch
  opengraph-image.png      # 1200x630 social preview
  twitter-image.png        # 1200x675 Twitter card
  manifest.ts              # PWA manifest with all icon refs

public/
  android-chrome-192x192.png
  android-chrome-512x512.png
  icon-maskable-192.png
  icon-maskable-512.png

If maintaining all those files manually sounds tedious, tools like AI Favicon can generate the full package from a text prompt. Describe the icon you want and you get all the files at the correct sizes, ready to drop into your project.